Vite Plugin
⚠️ Work in Progress: Vize is under active development and is not yet ready for production use. Test thoroughly before adopting in non-trivial projects.
Bundler status:
@vizejs/vite-pluginis currently the most stable bundler integration. For rollup / webpack / esbuild use@vizejs/unplugin, and for Rspack use@vizejs/rspack-plugin. Those non-Vite paths are still unstable and should be treated as experimental.
@vizejs/vite-plugin provides native-speed Vue SFC compilation for Vite projects. It is designed as a drop-in replacement for @vitejs/plugin-vue on Vue 3 SFCs — your existing <script setup> and Options API components work without modification.
Start with Vite+
For combined compilation, native Vue checks, linting, and formatting, keep settings in
vite.config.ts with the Vite+ helper:
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({});
Migration shows exactly which import and plugin calls to replace. The ordinary Vite path below replaces only the compiler.
Drop-in Scope
The drop-in claim is deliberately bounded, so it is worth stating what it does and does not cover:
- In scope — Vue 3 single-file components compiled through Vite, in both
<script setup>and Options API style, including scoped styles, CSS Modules, SSR, and HMR. - Incubating — Vue 2 and 2.7 (
vue.version: "2"/"2.7"). The legacy dialects are off by default and non-invasive: Vize does not compile.vuefiles in those modes, so your existing Vue compiler,vue-loader, or Nuxt 2 setup stays in charge. See Compiler Options. - Out of scope — webpack, rollup, esbuild, and Rspack.
@vizejs/unpluginand@vizejs/rspack-pluginexist but are experimental and carry no drop-in guarantee; see Experimental Bundler Integrations. - Not complete yet — plugin-option parity with
@vitejs/plugin-vue.include,exclude, andisProductionare honored today; every other documented option, the reason it diverges, and the remaining gaps are tracked in #3227.
Installation
Install vp once from the Vite+ install guide, then add the packages:
vp install -D @vizejs/vite-plugin
Add vize as a direct dependency only if your project imports shared config helpers from "vize"
or exposes package scripts such as vize:lint and vize:check.
Basic Usage
// vite.config.js
import { defineConfig } from "vite";
import vize from "@vizejs/vite-plugin";
export default defineConfig({
plugins: [vize()],
});
Replace @vitejs/plugin-vue with @vizejs/vite-plugin to compile through Rust. For combined Vite+ check, lint, format, and build tasks, use the Vite+ defineConfig().
TypeScript Vue Imports
Add the plugin package to compilerOptions.types to make direct .vue imports resolvable by
TypeScript without writing a local env.d.ts shim:
{
"compilerOptions": {
"types": ["vite/client", "@vizejs/vite-plugin"]
}
}
This does not require adding vize as a direct project dependency.
For Vite Plus projects, keep the Vite Plus client type and append the plugin package:
{
"compilerOptions": {
"types": ["vite-plus/client", "@vizejs/vite-plugin"]
}
}
For Vite+ projects, keep options in the integration helper's compiler field in
vite.config.ts. For ordinary Vite, use direct vize({ ... }) options. Shared
standalone config is optional when CLI or LSP commands also need those settings.
Optional standalone shared config
When CLI or LSP commands need the same settings, use defineConfig from vize
and a vize.config.* file. Install vize directly when importing that helper.
The standalone configuration reference preserves
file discovery, TypeScript/JSON/PKL examples, and scoped settings.
Vite+ integration tasks use the helper in vite.config.ts.
Compiler Options
Direct options passed to vize() override vize.config.*.
The full precedence is direct plugin options, then inline config, then vize.config.*, then
defaults.
vize({
vueVersion: 3,
sourceMap: true,
ssr: false,
vapor: false,
customRenderer: false,
templateSyntax: "standard",
scanPatterns: ["src/**/*.vue"],
ignorePatterns: ["node_modules/**", "dist/**", ".git/**"],
});
| Option | Where to set it | Description |
|---|---|---|
vueVersion |
vize({ vueVersion }) |
Set 0.11, 1, 2, or "legacy" to run in non-invasive legacy Vue compatibility mode and leave SFC compilation to the host compiler. |
sourceMap |
compiler.sourceMap or vize({ sourceMap }) |
Generate source maps whose sources name the authored .vue file. Defaults to development on, production off unless build.sourcemap is set. |
ssr |
compiler.ssr or vize({ ssr }) |
Force SSR compilation when Vite's SSR build flag is not enough. |
vapor |
compiler.vapor or vize({ vapor }) |
Compile templates through the Vapor backend. |
jsxMode |
compiler.jsxMode or vize({ jsxMode }) |
Default output backend ("vdom" / "vapor") for .jsx/.tsx components. Per-component "use vue:*" directives override it. |
customRenderer |
compiler.customRenderer or vize({ customRenderer }) |
Treat lowercase non-HTML tags as custom renderer elements. Does not match PascalCase tags such as <TresMesh>. |
customElements |
compiler.customElements or vize({ customElements }) |
Tag patterns compiled as custom elements instead of Vue components. Use ["Tres*"] for TresJS PascalCase renderer tags. |
templateSyntax |
compiler.templateSyntax or vize({ templateSyntax }) |
Choose "standard", "strict", or "quirks" template syntax handling. |
whitespace |
compiler.whitespace, vize({ whitespace }), or template.compilerOptions.whitespace |
Use Vue's "condense" (default) or "preserve" template whitespace mode. Vize also accepts "vue2-line-breaks" through its own compiler/Vite option to keep a newline after text or interpolation when Vue 3 would condense it to one space. This is a narrow migration mode, not full Vue 2 whitespace behavior. |
template.compilerOptions.comments |
vize({ template: { compilerOptions: { comments } } }) |
Preserve authored template comments in development by default and omit them in production. Set true or false to override either default. Direct native calls use templateComments and default to false. |
experimentals |
top-level experimentals or vize({ experimentals }) |
Fully opt-in Vue RFC and backend experiments. Missing keys, false, and null are off. |
include |
vite.include or vize({ include }) |
Files that the plugin should compile. |
exclude |
vite.exclude or vize({ exclude }) |
Files that the plugin should ignore. |
scanPatterns |
vite.scanPatterns or vize({ scanPatterns }) |
Glob patterns used for startup pre-compilation. |
ignorePatterns |
vite.ignorePatterns or vize({ ignorePatterns }) |
Glob patterns skipped during startup pre-compilation. |
configMode |
vize({ configMode }) |
Use "root", "auto", or false for shared config loading. |
configFile |
vize({ configFile }) |
Load a specific config file. |
config |
vize({ config }) |
Inline shared config for Vite Plus runtime settings. |
handleNodeModulesVue |
vize({ handleNodeModulesVue }) |
Compile .vue files imported from node_modules on demand. |
debug |
vize({ debug }) |
Print plugin debug logs. |
For the full experimentals flag table, opt-in rules, aliases, and shared-config precedence, see
Experimentals.
Common recipes:
// Vapor-oriented build
vize({ vapor: true });
// TresJS PascalCase renderer tags
vize({
customRenderer: true,
customElements: ["Tres*", "primitive"],
});
// Existing templates that rely on parser edge cases, such as
// v-for alias edge parens or `<div />` as a self-closing leaf
vize({ templateSyntax: "quirks" });
// Monorepo package with explicit scan roots
vize({
root: import.meta.dirname,
scanPatterns: ["src/**/*.vue", "examples/**/*.vue"],
});
// Legacy Vue / Nuxt 2 Bridge project with an existing host compiler plugin
vize({ vueVersion: 2 });
vueVersion: 0.11, 1, 2, and "legacy" are host-compiler compatibility modes. Vize does not
compile .vue files in these modes, does not expose the Vue 3 vite:vue API shim, and does not
inject Vue 3 bundler feature flags. Keep the existing Vue compiler plugin, vue-loader, or Nuxt 2's
own compiler configured normally.
How It Works
The plugin intercepts .vue file requests and compiles them using Vize's Rust-native pipeline through Node.js NAPI bindings:
Pre-compilation — At
buildStart, the plugin discovers all.vuefiles and compiles them in batch usingcompileBatch. This triggers Rayon-based parallel compilation on the Rust side, processing all files across all CPU cores simultaneously.On-demand compilation — During development, if a
.vuefile is requested that isn't in the cache (e.g., dynamically imported), it's compiled on-the-fly viacompileFile.HMR — When a
.vuefile changes, only that file is recompiled. The plugin detects whether the change is style-only and applies a style-only HMR update when possible, avoiding a full component re-render.CSS extraction — In production builds, all scoped CSS from Vue components is extracted and merged into
assets/vize-components.css, eliminating per-component style injection overhead.
Compilation Pipeline
.vue file
→ Armature (Parser) — Tokenizes and parses the SFC structure
→ Croquis (Semantic Analysis) — Analyzes template expressions and bindings
→ Atelier (Compilation) — Generates optimized JavaScript output
→ Vitrine (NAPI Binding) — Delivers the result to Node.js
→ Vite module graph — Served as a virtual module
The same semantic analysis layer is reused by linting and type checking. See Static Analysis for the diagnostic side of the pipeline.
Comparison
| Feature | @vitejs/plugin-vue | @vizejs/vite-plugin |
|---|---|---|
| Language | JavaScript | Rust (NAPI) |
| SFC Compilation | Yes | Yes |
| Template Compilation | Yes | Yes |
| Script Setup | Yes | Yes |
| CSS Scoping | Yes | Yes |
| SSR Support | Yes | Yes |
| HMR | Yes | Yes (style-only optimization) |
| Batch Pre-compilation | No | Yes (parallel via Rayon) |
| CSS Extraction | Per-component | Merged single file |
| Vapor Mode | Experimental | First-class (vize_atelier_vapor) |
| Plugin Options | Full documented surface | include / exclude / isProduction; see #3227 |
Advanced Features
Batch Pre-compilation
Unlike @vitejs/plugin-vue, which compiles each .vue file on first request, Vize pre-compiles all discovered .vue files at build start using multi-threaded batch compilation. This means:
- Dev server startup — All components are ready before the first page load
- Production builds — Maximum parallelism from the start
Static Asset Rewriting
The plugin automatically rewrites static asset URLs in templates. For example:
<template>
<img src="./logo.png" />
</template>
The src attribute is hoisted to an import statement, allowing Vite to process the asset through its asset pipeline (hashing, optimization, etc.).
Define Replacement
Vite normally skips import.meta.* replacement for virtual modules (prefixed with \0). Vize's plugin manually applies define replacements to ensure import.meta.env.* values work correctly in compiled Vue components.
Per-Environment Isolation
For Nuxt compatibility, the plugin isolates define values per Vite environment (client vs. server/SSR). This prevents client-side environment values from leaking into SSR output.
Nuxt Compatibility
The plugin exposes a compatibility shim for tools that probe for @vitejs/plugin-vue's API (like Nuxt). This means Vize works with Nuxt's built-in Vue integration without special configuration:
// nuxt.config.ts — using the dedicated Nuxt module
export default defineNuxtConfig({
modules: ["@vizejs/nuxt"],
vize: {
compiler: true,
},
});
See Nuxt Integration for more details.
Notes
- The plugin requires
@vizejs/nativefor Node.js NAPI bindings (installed automatically as a dependency) - Vapor mode compilation is available via
vize_atelier_vapor(Vue 3.6+) - VDOM compilation uses
vize_atelier_dom - The plugin supports
virtual:vize-stylesfor importing all compiled CSS as a module .jsx/.tsxVue components are compiled automatically through the same plugin — see the JSX & TSX guide- For experimental rollup / webpack / esbuild / Rspack support, see Experimental Bundler Integrations