| | |

Vite 32 ⚡ Cheatsheet

⏱️ Estimated read: 7 min | |

This cheatsheet covers Vite 8 (Rolldown-powered) with the Environment API, advanced chunking, Oxc transforms, and the experimental Bundled Dev Mode. It is scoped to the decisions you make mid-build, not to every option in the config.


The Core Shift in Vite 8

Vite 8 replaced esbuild + Rollup with Rolldown (Rust bundler) and Oxc (Rust transformer/minifier) . The build is 7.7× faster, memory usage is halved, and the dev server starts roughly 3× faster .

MetricVite 7Vite 8
Build time (Linear)46s6s
Dev server startup~3s~1s
Memory usage~800MB~400MB

The Config Renames

Every old option still works through an auto-conversion shim, but the shim will be removed. The new names are the ones to write.

Vite 7Vite 8
build.rollupOptionsbuild.rolldownOptions
worker.rollupOptionsworker.rolldownOptions
optimizeDeps.esbuildOptionsoptimizeDeps.rolldownOptions
esbuildoxc
esbuild.jsxFactoryoxc.jsx.pragma
esbuild.jsxFragmentoxc.jsx.pragmaFrag
esbuild.jsx: 'automatic'oxc.jsx: { runtime: 'automatic' }
transformWithEsbuildtransformWithOxc

The esbuild.banner and esbuild.footer options have no Oxc equivalent. Use a custom plugin transform hook instead .


The Minifier and the Casing Trap

JavaScript minification now uses Oxc by default. CSS minification uses Lightning CSS . The build.minify: 'esbuild' fallback requires esbuild as a dev dependency and is deprecated.

The Oxc minifier options live on build.rolldownOptions.output.minify, and the casing is snake_case. drop_console works; dropConsole silently does nothing .

// ✅ Correct
build: {
  rolldownOptions: {
    output: {
      minify: {
        compress: {
          drop_console: true, // snake_case
        },
      },
    },
  },
},

Property mangling (mangleProps, reserveProps, mangleQuoted, mangleCache) is not supported by Oxc .


The Chunking Shift: advancedChunks

manualChunks is deprecated. The Vite 8 mechanism is advancedChunks, a declarative grouping system with priority and size constraints .

build: {
  rolldownOptions: {
    output: {
      advancedChunks: {
        groups: [
          {
            name: 'react-vendor',
            test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
            priority: 20,
          },
          {
            name: 'charts',
            test: /[\\/]node_modules[\\/](recharts|d3)[\\/]/,
            priority: 15,
            maxSize: 300000,
          },
          {
            name: 'vendor',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            maxSize: 500000,
          },
        ],
      },
    },
  },
},

priority decides which group wins when a module matches multiple tests. maxSize auto-splits a group that grows too large . The manualChunks object form is removed; the function form is deprecated.


The Environment API (Stable from Vite 7)

The environments config declares multiple runtimes in a single build. The client and ssr environments are the baseline; edge is the third case that forces the abstraction .

export default defineConfig({
  environments: {
    client: { build: { outDir: 'dist/client' } },
    ssr: { build: { outDir: 'dist/server', ssr: true } },
    edge: {
      resolve: { noExternal: true, conditions: ['edge', 'worker'] },
      build: { outDir: 'dist/edge', target: 'es2022' },
    },
  },
});

Each environment has its own moduleGraph and transformRequest(). Plugins access the current environment with this.environment.name . The server.moduleGraph and ssrLoadModule APIs still work for backward compatibility, but the environment instances are the forward-compatible surface .


The Plugin Hook Filter

In Vite 8, transform hooks accept a filter property that moves the match check to Rust. The handler is only called when the filter matches, which avoids a Rust-to-JS call for non-matching modules .

transform: {
  filter: {
    id: /\.(ts|tsx)$/,
  },
  handler(code, id) {
    return { code, map: null };
  },
},

The id filter accepts a RegExp or a glob string. The moduleType and code filters are also available. The filter is only on resolveId, load, transform, and renderChunk .


The Library Mode Contract

Library mode has three manual steps that Vite does not do for you .

StepConfigurationConsequence if missed
Externalize peersrolldownOptions.externalDuplicate runtime in consumer
Generate typesvite-plugin-dtsTypeScript sees no types
Map exportsexports field in package.jsonResolver fails
export default defineConfig({
  plugins: [dts({ include: ['src'], rollupTypes: true })],
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      name: 'MyLib',
      fileName: (format) => `my-lib.${format}.js`,
    },
    rolldownOptions: {
      external: ['react', 'react-dom', 'react/jsx-runtime'],
      output: { globals: { react: 'React', 'react-dom': 'ReactDOM' } },
    },
  },
});

The package.json must declare peerDependencies for the externalized packages, and the exports map must point to the actual output filenames with types first .


The Bundled Dev Mode (Experimental)

For large applications, the unbundled dev server’s request count becomes the bottleneck. Bundled Dev Mode serves a Rolldown-bundled output during development .

MetricUnbundledBundled Dev Mode
10,000 components startupBaseline~15× faster
10,000 components full reloadBaseline~10× faster
Linear cold startBaseline~3× faster
Linear network requestsBaseline~10× fewer
HMR speed~50msUnchanged

Enable with experimental.bundledDev: true or --experimental-bundle. The compatibility surface is narrower: third-party plugins and minor features may not work .


The CommonJS Interop Change

The default import from a CJS module now resolves to module.exports if the importer is .mjs, the nearest package.json has "type": "module", or module.exports.__esModule is not true. Otherwise it resolves to module.exports.default .

// Temporary escape hatch
legacy: { inconsistentCjsInterop: true }

The legacy option is deprecated. The permanent fix is to report the package or switch to an ESM version .


The SSR Primitives

Vite’s SSR support is low-level: middleware mode, transformIndexHtml, ssrLoadModule, and import.meta.env.SSR.

// The middleware server
const vite = await createViteServer({
  server: { middlewareMode: true },
  appType: 'custom',
});

app.use(vite.middlewares);
app.use('*all', async (req, res) => {
  let template = fs.readFileSync('index.html', 'utf-8');
  template = await vite.transformIndexHtml(url, template);
  const { render } = await vite.ssrLoadModule('/src/entry-server.js');
  const html = template.replace('<!--ssr-outlet-->', await render(url));
  res.status(200).set({ 'Content-Type': 'text/html' }).end(html);
});

The ssrLoadModule loads the server entry without a bundle. The ssrFixStacktrace remaps the errors .


The Path Alias Dual Config

Vite does not read tsconfig.json paths. The alias must be declared in both files.

// tsconfig.json
"paths": { "@/*": ["./src/*"] }
// vite.config.ts
resolve: {
  alias: { '@': path.resolve(__dirname, './src') },
},

Dynamic imports may require optimizeDeps.exclude: ['@'] to prevent the scanner from treating @ as an npm scope.


The Monorepo Linked Package Rule

Vite treats linked workspace packages as source, not as dependencies.

Package typeConfiguration
CommonJSoptimizeDeps.include: ['pkg'] + build.commonjsOptions.include
ESMoptimizeDeps.exclude: ['pkg']
React duplicateresolve.dedupe: ['react', 'react-dom'] + peer dep

The resolve.preserveSymlinks option is a yarn workaround that breaks hoisted dependencies in some setups. Use it only when the linked package is not resolved otherwise.


The Deployment Routing Rule

A Vite SPA needs a history-fallback rewrite on the host. The rule is host-specific.

HostRule
Netlify/* /index.html 200 in _redirects
Vercel"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
Cloudflare Pages/* /index.html 200 in _redirects
Nginxtry_files $uri $uri/ /index.html;

The base option must match the deployment path. The router’s basename must match the base.


The CLI Quick Reference

vite                          # Dev server
vite build                    # Production build
vite preview                  # Preview the build
vite build --ssr              # SSR build
vite --experimental-bundle    # Bundled Dev Mode
vite --config my-config.js    # Custom config

The One-Line Summary

Rolldown bundles. Oxc transforms. Environments separate. Chunks are declarative. Auth the actions, narrow the props, and place the boundary at the leaf.

The old config still works through the shims, but the new names are the ones that will survive. The advancedChunks is the chunking mechanism. The environments object is the multi-runtime mechanism. The filter is the plugin performance mechanism. The external is the library contract. The rest is the deployment.


Summary

AreaKey change in Vite 8
BundlerRolldown replaces Rollup and esbuild
TransformerOxc replaces esbuild
Config renamerollupOptions → rolldownOptions, esbuild → oxc
MinifierOxc for JS, Lightning CSS for CSS
ChunkingadvancedChunks replaces manualChunks
Environmentsenvironments config for client/ssr/edge
Plugin filtertransform.filter moves the match to Rust
Library modeExternalize peers, generate types, map exports
Bundled devexperimental.bundledDev: true
CJS interopChanged default import behavior

Remember: Vite 8 is the Rolldown release. The build is faster, the config is renamed, and the chunking is declarative. The old options still work through the shims, but the shims are temporary. The advancedChunks is the chunking mechanism, the environments object is the multi-runtime mechanism, and the filter is the plugin performance mechanism. The rest is the deployment rule and the library contract. The cheatsheet is the decisions, and the decisions are the discipline.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!