Documentsdify
Vite Configuration
Vite Configuration
Type
Topic
Status
Published
Created
Jul 8, 2026
Updated
Jul 8, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Vite Configuration#

Entry point: web/vite.config.ts

The Dify frontend uses Vite (via the vite-plus wrapper) as its build and dev-server pipeline. The configuration in web/vite.config.ts is a single defineConfig factory that branches on three mutually exclusive runtime modes — test, Storybook, and normal dev/build — to assemble the appropriate plugin set for each context.


Runtime Mode Detection#

Two boolean flags drive plugin selection :

FlagDetection logic
isTestmode === 'test' (Vitest sets this)
isStorybookprocess.env.STORYBOOK === 'true' OR any CLI arg contains "storybook"

Plugin Sets#

Plugins are chosen based on the active mode :

Test mode (isTest)

  • nextStaticImageTestPlugin — transforms static image imports into stub objects for unit tests
  • react() — JSX transform
  • mdx-stub — inline plugin that stubs .mdx imports (export default () => null) so components importing MDX can be unit-tested without a full MDX pipeline

Storybook mode (isStorybook)

  • react() only

All other plugins are intentionally excluded. vite-plugin-inspect would crash Storybook with Error: Can not found environment context for client . The fix — introduced in PR #33039 — added the isStorybook flag and reduced the Storybook plugin list to the minimum viable set.

Normal dev/build mode

  • Inspect() — vite-plugin-inspect for build pipeline introspection
  • createCodeInspectorPlugin / createForceInspectorClientInjectionPlugin — custom plugins for click-to-source code inspection
  • tailwindcss()@tailwindcss/vite plugin
  • react() — JSX transform
  • vinext({ react: false }) — Next.js-to-Vite compatibility layer
  • customI18nHmrPlugin — hot-reloads i18n JSON files without a full page reload

Module Resolution#

resolve block:

  • tsconfigPaths: true — delegates path alias resolution to tsconfig.json, replacing the older manual resolve.alias entry for ~@. Switched in PR #33363.
  • loro-crdt alias — maps bare loro-crdt imports to loro-crdt/base64 . The default loro-crdt package uses a WebAssembly loader that is incompatible with Vite-based pipelines (Vitest and vinext); the base64 build inlines WASM as a Base64 string, sidestepping the loader issue.

vinext-Specific Config#

The optimizeDeps, server, and ssr settings only apply in normal dev/build mode (!isTest && !isStorybook) :

  • optimizeDeps.exclude: ['@tanstack/react-query'] — prevents pre-bundling conflicts with vinext
  • server.port: 3000
  • ssr.noExternal: ['emoji-mart'] — avoids CJS named-export errors for emoji-mart under SSR

Vitest Config#

The test block is always present in the exported config and configures Vitest :

  • Pool: threads
  • Environment: happy-dom
  • Globals: enabled
  • Setup file: ./vitest.setup.ts
  • Coverage: v8 provider; JSON reporters in CI, text + JSON locally

Custom Vite Plugins#

All project-local plugins live in web/plugins/vite/:

FilePurpose
code-inspector.tsClick-to-source code inspector, injected into dev client
custom-i18n-hmr.tsHMR for i18n JSON files
inject-target.tsResolves instrumentation-client.ts as the injection target
next-static-image-test.tsStubs static image imports for unit tests
utils.tsShared helpers for module ID normalization and client code injection

Storybook Config#

Storybook configuration lives in web/.storybook/main.ts. It uses the @storybook/nextjs-vite framework and scans for stories in app/components/** and features/** . Vite configuration for Storybook is sourced from the same shared vite.config.ts, controlled by the isStorybook flag.