Vite is a fast build tool and dev server for modern web apps. In a Vite monorepo, Nx runs and caches Vite tasks across every project so you only rebuild what changed.
The @nx/vite plugin adds inferred tasks and project configuration generators.
You can use Vite with Nx without the plugin and still get task caching, task orchestration, and the project graph.
Requirements
Section titled “Requirements”The @nx/vite plugin supports the following package versions.
| Package | Supported Versions |
|---|---|
vite | ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 |
For supported vitest versions, see the @nx/vitest plugin requirements.
Nx generators install the latest supported versions automatically when scaffolding new projects.
Add to an existing workspace
Section titled “Add to an existing workspace”Install the plugin:
nx add @nx/viteConfigure an existing project to use Vite:
nx g @nx/vite:configuration --project=my-appVerify inferred tasks in the project details view:
nx show project my-app --webReplace my-app with your project name.
Create a new workspace
Section titled “Create a new workspace”Use a framework preset and keep the setup minimal:
npx create-nx-workspace@latest --preset=react-standalone --bundler=vitenpx create-nx-workspace@latest --preset=web-components --bundler=viteFor the full framework workflows, see the React introduction or Web app reference.
Local development
Section titled “Local development”nx dev my-appstarts the Vite dev server for the project (same as the deprecatedservetarget).nx build my-appcreates a production build indist/(controlled bybuild.outDirinvite.config.*) and registers the outputs for Nx caching.nx preview my-appserves the production build using Vite preview (runs afterbuild).nx serve-static my-appserves the built assets fromdist/for quick smoke tests.nx typecheck my-appruns TypeScript typechecking.@nx/js/typescriptinfers this task, except for Vue projects, which get avue-tsctask from@nx/vite/plugin.
Replace my-app with your project name.
Configuration
Section titled “Configuration”Configure task inference
Section titled “Configure task inference”The @nx/vite plugin infers tasks by reading Vite config files. Any of the following config files will be picked up:
vite.config.jsvite.config.tsvite.config.mjsvite.config.mtsvite.config.cjsvite.config.cts
The configuration directory must also contain a package.json or project.json.
Build tasks are only created when the project is buildable. A project is treated as buildable when any of the following are true:
build.libis set invite.config.*build.rollupOptions.inputorbuild.rolldownOptions.inputis set (Vite 8 usesrolldownOptions)builder.buildAppis set- an
index.htmlfile exists at the project root
Dev, preview, and serve-static tasks are created for buildable projects. If you are in library mode (build.lib), these tasks are skipped unless you explicitly configure a dev server (e.g. server.host or server.port).
Typecheck tasks are only created for Vue projects that have a tsconfig*.json file, and they run vue-tsc. Other projects get their typecheck task from @nx/js/typescript, which the @nx/vite:init generator registers when it's missing.
Plugin options
Section titled “Plugin options”Configure @nx/vite/plugin in the plugins array in nx.json:
{ "plugins": [ { "plugin": "@nx/vite/plugin", "options": { "buildTargetName": "build", "previewTargetName": "preview", "serveTargetName": "serve", "devTargetName": "dev", "serveStaticTargetName": "serve-static", "typecheckTargetName": "typecheck", "buildDepsTargetName": "build-deps", "watchDepsTargetName": "watch-deps" } } ]}serveTargetName is deprecated; use devTargetName instead. buildDepsTargetName and watchDepsTargetName create tasks that build or watch project dependencies.
| Option | Description | Default |
|---|---|---|
buildTargetName | Name of the Vite build task | build |
previewTargetName | Name of the Vite preview task | preview |
serveTargetName | Name of the deprecated Vite serve task | serve |
devTargetName | Name of the Vite dev server task | dev |
serveStaticTargetName | Name of the static file server task | serve-static |
typecheckTargetName | Name of the Vue vue-tsc typecheck task, or false to skip it | typecheck |
compiler | Vue typecheck compiler: vue-tsc, tsc, or tsgo | auto-detected |
buildDepsTargetName | Name of the build-deps task for dependency builds | none |
watchDepsTargetName | Name of the watch-deps task for dependency watches | none |
The build and typecheck tasks are cached, with build outputs based on your Vite configuration. The dev, preview, and static-server tasks are continuous. When compiler is omitted, Nx uses vue-tsc when it detects a Vite Vue plugin. Set compiler to tsc or tsgo to drop the vue-tsc task and let @nx/js/typescript provide typecheck instead. To typecheck with tsgo, set compiler: 'tsgo' on @nx/js/typescript, which ignores the Vite plugin's compiler.
Wait for the dev server to be ready
Section titled “Wait for the dev server to be ready”The inferred dev and preview targets come with a readyWhen check, so a task can wait until the server accepts requests instead of only until it has started. The nxReadySignal() plugin reports the dev or preview server's address to Nx once it listens. Generated app configs include it, and nx migrate adds it to existing application configs when you update to Nx 24. In any other config, import it from @nx/vite/plugins/nx-ready-signal.plugin and add it to plugins in vite.config.*. The report carries the address the server actually listens on, so the waiting task tests against it however the port was chosen.
Without the plugin, the check resolves the Vite config when the task runs instead, in the task's environment and with its options. That covers .env files and the --port, --host, and --mode (-m) flags. It takes the port from the --port flag, server.port or preview.port, or the Vite defaults of 5173 and 4173, and waits for it. With a port of 0, the server picks its own port. There's nothing to wait for then, and the target counts as ready once it has started. If another process holds the configured port and Vite moves to the next free one, this check can pass before the server is up. The serve-static target's file server reports its address once it listens.
A dependent task starts as soon as the server task has started, unless its dependsOn entry sets waitFor to ready:
{ "targets": { "e2e": { "dependsOn": [ { "projects": "myapp", "target": "dev", "waitFor": "ready" } ] } }}The waiting task gets the server's address in the NX_READY_URL environment variable, when exactly one target it waits for reported one. A readyWhen on the target in targetDefaults or in the project configuration replaces the inferred check, and null turns it off. For the other checks, see wait for a continuous task to be ready. For signaling from your own server, see signal readiness from the task.
Disable or scope inference
Section titled “Disable or scope inference”To stop inference for a specific project, exclude its config file with include/exclude filters in nx.json:
{ "plugins": [ { "plugin": "@nx/vite/plugin", "exclude": ["apps/legacy/**"] } ]}To avoid specific targets, adjust the config files that trigger them. For example, use library mode (build.lib) to skip dev, preview, and serve-static unless you set dev server options.
View inferred tasks
Section titled “View inferred tasks”To see what tasks Nx inferred for a project, open the project details view in Nx Console or run:
nx show project my-app --webA target defaults plugin filter for these tasks must use the exact identifier @nx/vite/plugin.
Set up CI for your Vite monorepo
Section titled “Set up CI for your Vite monorepo”In CI, Nx runs nx affected to rebuild and retest only the projects a change touches, and caches results to skip repeated work.
For a complete pipeline, see Set up CI.