Skip to main content

Vite Config Cheatsheet — 60+ vite.config.ts Options with Defaults and Examples

Vite config cheat sheet — 60+ vite.config.ts options with defaults, examples, and pitfalls.

  • Runs locally
  • Category Developer & DevOps
  • Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
Section:
39 options
Server(9)
server.port
Type: numberDefault: 5173

The port the dev server listens on. If the port is already in use, Vite will automatically try the next available port unless `server.strictPort` is set to `true`.

Example
server: {
  port: 3000,
}
server.host
Type: string | booleanDefault: 'localhost'

Set to `"0.0.0.0"` or `true` to expose the dev server on all network interfaces, including LAN and public addresses. Required when testing on a mobile device on the same network.

Pitfall:

Exposing the dev server on all interfaces can be a security risk on public networks. Use with caution and only on trusted networks.

Example
server: {
  host: true,      // same as '0.0.0.0'
}
server.open
Type: boolean | stringDefault: false

Automatically open the app in the browser when the server starts. Pass a URL string to open a specific page, e.g. `"/dashboard"` to skip the homepage.

Example
server: {
  open: true,
  // or: open: '/dashboard',
}
server.proxy
Type: Record<string, string | ProxyOptions>Default: undefined

Configure custom proxy rules for the dev server. Requests matching the key pattern are forwarded to the target. Use `changeOrigin: true` when the target is on a different hostname. Use `rewrite` to strip a path prefix the backend does not expect.

Pitfall:

Forgetting `changeOrigin: true` when the proxy target is on a different hostname causes the backend to reject requests because the `Host` header does not match.

Example
server: {
  proxy: {
    '/api': {
      target: 'http://localhost:3001',
      changeOrigin: true,
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
    '/ws': {
      target: 'ws://localhost:3001',
      ws: true,
    },
  },
}
server.cors
Type: boolean | CorsOptionsDefault: true (for *.localhost and 127.0.0.1)

Configure CORS for the dev server. Set to `true` to allow all origins, or pass a `CorsOptions` object for fine-grained control. Useful when testing your dev server from a different origin.

Example
server: {
  cors: true,
  // or fine-grained:
  // cors: {
  //   origin: 'https://example.com',
  //   methods: ['GET', 'POST'],
  // },
}
server.hmr
Type: boolean | HmrOptionsDefault: true

Enable or disable HMR (Hot Module Replacement). Set `hmr: false` to disable. Pass an object to configure the HMR WebSocket connection — useful when running Vite behind a reverse proxy that does not forward WebSocket connections correctly.

Pitfall:

When running Vite behind a reverse proxy (nginx, Caddy), HMR WebSocket connections often fail because the proxy is not configured to forward WebSocket upgrades. Add the HMR overlay host explicitly to fix it.

Example
server: {
  hmr: {
    protocol: 'ws',
    host: 'localhost',
    port: 5173,
  },
}
server.headers
Type: OutgoingHttpHeadersDefault: undefined

Specify custom HTTP response headers for the dev server. Use to add security headers like `Cross-Origin-Opener-Policy` or to enable `SharedArrayBuffer` which requires `Cross-Origin-Embedder-Policy: require-corp`.

Example
server: {
  headers: {
    'Cross-Origin-Opener-Policy': 'same-origin',
    'Cross-Origin-Embedder-Policy': 'require-corp',
  },
}
server.strictPort
Type: booleanDefault: false

When set to `true`, Vite exits with an error if the configured port is already in use instead of silently trying the next port. Useful in CI environments or scripts that depend on a specific port.

Example
server: {
  port: 3000,
  strictPort: true,
}
preview.port
Type: numberDefault: 4173

The port used by `vite preview`, which serves the production build locally. Separate from `server.port` to avoid conflicts when running both simultaneously.

Example
preview: {
  port: 8080,
  open: true,
}
Build(12)
build.target
Type: string | string[]Default: 'modules'

The browser compatibility target for the production build. `"modules"` targets browsers with native ES module support (Chrome 87+, Firefox 78+, Safari 14+). Use `"esnext"` for the latest syntax. Pass an array like `["chrome87", "firefox78", "safari14"]` to target a specific browser set. Uses esbuild transforms for syntax lowering.

Pitfall:

Setting `target: "esnext"` does no syntax downleveling — it assumes the browser supports all latest JS features. Use a specific year (e.g. "es2020") for production apps targeting older browsers.

Example
build: {
  target: 'es2020',
  // or: target: ['chrome87', 'firefox78', 'safari14'],
}
build.outDir
Type: stringDefault: 'dist'

The output directory for the production build, relative to the project root. Vite will empty this directory before building if `build.emptyOutDir` is `true`.

Example
build: {
  outDir: 'dist',
}
build.assetsDir
Type: stringDefault: 'assets'

Subdirectory inside `outDir` where generated assets (JS chunks, CSS, images) are placed. The full path of a chunk is `{outDir}/{assetsDir}/[name]-[hash].js`.

Example
build: {
  assetsDir: 'static',   // outputs to dist/static/
}
build.emptyOutDir
Type: booleanDefault: true if outDir is inside root

Clears the output directory before building. Defaults to `true` when `outDir` is inside the project root, `false` when it is outside (to prevent accidental deletion). Set explicitly to `true` to always clean.

Example
build: {
  emptyOutDir: true,
}
build.minify
Type: boolean | 'terser' | 'esbuild'Default: 'esbuild'

Controls JS minification. `"esbuild"` is the default and is very fast. `"terser"` produces slightly smaller output but is 20-40× slower. Set to `false` to disable minification entirely — useful for debugging production builds.

Example
build: {
  minify: 'esbuild',    // fast (default)
  // minify: 'terser',  // smaller, slower
  // minify: false,     // disable for debugging
}
build.sourcemap
Type: boolean | 'inline' | 'hidden'Default: false

Generate source maps for the production build. `true` creates separate `.map` files. `"inline"` embeds the source map as a data URI in the bundle. `"hidden"` creates `.map` files without the `//# sourceMappingURL` comment — use with error monitoring tools that upload maps privately.

Example
build: {
  sourcemap: true,
  // or 'inline' | 'hidden'
}
build.rollupOptions
Type: RollupOptionsDefault: {}

Directly customize the Rollup bundle configuration. Commonly used to configure `external` dependencies for libraries, `output.manualChunks` for code splitting, and `input` for multi-page apps. Full Rollup API is available.

Example
build: {
  rollupOptions: {
    external: ['react', 'react-dom'],
    output: {
      globals: {
        react: 'React',
        'react-dom': 'ReactDOM',
      },
      manualChunks: {
        vendor: ['lodash', 'axios'],
      },
    },
  },
}
build.lib
Type: LibraryOptionsDefault: undefined

Configure Vite in library mode for publishing npm packages. Specify the entry point and output formats. Always set `rollupOptions.external` to list peer dependencies that should not be bundled.

Example
build: {
  lib: {
    entry: 'src/index.ts',
    name: 'MyLib',
    fileName: 'my-lib',
    formats: ['es', 'cjs'],
  },
  rollupOptions: {
    external: ['react', 'react-dom'],
  },
}
build.cssCodeSplit
Type: booleanDefault: true

When enabled (default), CSS imported by async JS chunks is split into separate CSS files. When disabled, all CSS is combined into a single file. Set to `false` when building a library to keep CSS in JS, or when you want a single CSS bundle.

Example
build: {
  cssCodeSplit: true,   // default, split per chunk
  // cssCodeSplit: false,  // one CSS file
}
build.assetsInlineLimit
Type: numberDefault: 4096 (4 KB)

Assets smaller than this threshold (in bytes) are inlined as base64 data URIs instead of being emitted as separate files. Reduces HTTP requests for small assets at the cost of larger JS/CSS bundle size. Set to `0` to disable inlining.

Example
build: {
  assetsInlineLimit: 8192,   // 8 KB
  // assetsInlineLimit: 0,   // never inline
}
build.chunkSizeWarningLimit
Type: numberDefault: 500 (kB)

Chunk size warning threshold in kB. Vite warns when a chunk exceeds this size. Increase the limit only if you have verified that large chunks are acceptable; better to use `rollupOptions.output.manualChunks` to split them.

Pitfall:

Raising this limit to suppress warnings is not a fix — large chunks harm page load performance. Investigate with `npx vite-bundle-visualizer` and split the offending chunks using `manualChunks`.

Example
build: {
  chunkSizeWarningLimit: 1000,   // 1 MB
}
build.copyPublicDir
Type: booleanDefault: true

When `true`, files in the `public/` directory are copied to `outDir` at the end of the build. Set to `false` when building a library — libraries do not need the public directory contents.

Example
build: {
  copyPublicDir: false,   // useful for library builds
}
Resolve(4)
resolve.alias
Type: Record<string, string> | Alias[]Default: {}

Define file system path aliases. Any import matching a key is replaced with the corresponding path value at build time. The most common use is creating a `@/` alias for the `src/` directory. Remember to add matching `paths` in `tsconfig.json` — Vite and TypeScript alias configs are independent.

Pitfall:

Setting `resolve.alias` in Vite but not in `tsconfig.json` paths causes TypeScript to report "Cannot find module" on every aliased import even though Vite resolves files correctly.

Example
import path from 'path';
import { defineConfig } from 'vite';

export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@utils': path.resolve(__dirname, './src/utils'),
    },
  },
});
resolve.extensions
Type: string[]Default: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']

File extensions tried when resolving bare imports without an extension. The default list covers the common TypeScript and JavaScript extensions. Avoid adding `.vue`, `.svelte`, etc. here — framework plugins handle those.

Example
resolve: {
  extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],
}
resolve.conditions
Type: string[]Default: ['module', 'browser', 'development|production']

Conditions checked against the `exports` field in `package.json`. Vite uses `"browser"` in the client build and `"node"` in SSR. Add custom conditions to resolve package entry points differently per environment.

Example
resolve: {
  conditions: ['module', 'browser'],
}
resolve.dedupe
Type: string[]Default: []

Force specific packages to resolve to the same instance. Prevents duplicate instances in the module graph, which can cause issues with singletons (React context, Vue reactivity system). Useful when using local packages via `file:` links or monorepos.

Pitfall:

The most common symptom of a missing `dedupe` entry is: React hooks throwing "Invalid hook call" or Vue components losing reactivity — caused by two copies of React/Vue being loaded.

Example
resolve: {
  dedupe: ['react', 'react-dom'],
}
Plugins(5)
plugins
Type: (Plugin | Plugin[])[]Default: []

Array of Vite plugins. Plugins are applied in order. Framework plugins (e.g. `@vitejs/plugin-react`) should generally come first. You can return `null` or `false` inside the array to conditionally skip a plugin.

Example
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    react(),
  ],
});
plugins (conditional)
Type: Plugin | false | nullDefault: n/a

Load a plugin only in specific modes by using a ternary or logical AND inside the plugins array. `false` and `null` values are filtered out by Vite. The `command` and `mode` parameters from `defineConfig` let you enable plugins only for builds or only in production.

Example
export default defineConfig(({ command, mode }) => ({
  plugins: [
    react(),
    mode === 'production' && vitePWA(),  // only in prod
    command === 'build' && bundleAnalyzer(),
  ].filter(Boolean),
}));
defineConfig
Type: UserConfig | ConfigEnv => UserConfigDefault: n/a

Helper function that provides TypeScript autocomplete for the config object. Pass a function to receive `command` (`"serve"` | `"build"`), `mode` (e.g. `"development"` | `"production"`), and `isSsrBuild` — useful for environment-aware configuration.

Example
import { defineConfig } from 'vite';

export default defineConfig(({ command, mode }) => {
  return {
    build: {
      sourcemap: command === 'serve',   // sourcemap in dev only
    },
  };
});
define
Type: Record<string, any>Default: {}

Define global constant replacements. Values are replaced as-is in the source code (not quoted). `import.meta.env.VITE_*` should be preferred for runtime env vars, but `define` is useful for build-time constants like feature flags and version strings.

Pitfall:

String values must be wrapped in `JSON.stringify()`. Writing `__VERSION__: "1.0"` inserts the literal `1.0` identifier into source — use `__VERSION__: JSON.stringify("1.0")` instead.

Example
define: {
  __APP_VERSION__: JSON.stringify('1.2.3'),
  __FEATURE_FLAG__: true,
}
base
Type: stringDefault: '/'

The public base path when served in development or production. Must include a trailing slash. Set to `"/sub-path/"` when deploying to a sub-directory (GitHub Pages, Netlify sub-paths). All asset URLs will be prefixed with this value.

Pitfall:

Missing a trailing slash (e.g. `base: "/my-app"` instead of `"/my-app/"`) causes incorrect asset URL generation in some cases. Always include the trailing slash.

Example
export default defineConfig({
  base: '/my-app/',   // deployed to example.com/my-app/
});
CSS(4)
css.modules
Type: CSSModulesOptionsDefault: {}

Configure CSS Modules behavior. `localsConvention: "camelCaseOnly"` converts dashed class names to camelCase in JS. `generateScopedName` lets you customize the scoped class name format — useful for readable class names in development.

Example
css: {
  modules: {
    localsConvention: 'camelCaseOnly',
    generateScopedName: '[name]__[local]__[hash:5]',
  },
}
css.preprocessorOptions
Type: Record<string, object>Default: {}

Pass options to CSS preprocessors (Sass, Less, Stylus). The most common use is injecting global variables or imports so they are available in every style file without explicit imports.

Example
css: {
  preprocessorOptions: {
    scss: {
      additionalData: '@use "@/styles/variables" as *;',
    },
    less: {
      globalVars: {
        primaryColor: '#1890ff',
      },
    },
  },
}
css.postcss
Type: string | PostCSSConfigDefault: auto-discovered postcss.config.js

Inline PostCSS configuration or a path to a PostCSS config file. Use to configure plugins like `autoprefixer` and `cssnano`. When specified here, Vite does not search for an external `postcss.config.js` file.

Example
import autoprefixer from 'autoprefixer';

css: {
  postcss: {
    plugins: [
      autoprefixer(),
    ],
  },
}
css.devSourcemap
Type: booleanDefault: false

Enable CSS source maps in development. When enabled, browser DevTools shows the original CSS file location instead of the transformed output. Has a slight performance cost — leave disabled unless you are actively debugging CSS.

Example
css: {
  devSourcemap: true,
}
Optimize(5)
optimizeDeps.include
Type: string[]Default: []

Force-include specific dependencies in the pre-bundling step. Useful for dependencies that are not automatically detected (e.g. deeply nested imports, dynamic imports). Entries must be resolvable import paths, not file system paths.

Example
optimizeDeps: {
  include: ['lodash-es', 'some-cjs-dep > nested-dep'],
}
optimizeDeps.exclude
Type: string[]Default: []

Exclude specific dependencies from pre-bundling. Use for ESM-native packages that have circular dependencies or ship broken CJS builds that esbuild handles incorrectly. Also useful for large packages where you only use a small part.

Example
optimizeDeps: {
  exclude: ['@ffmpeg/ffmpeg', 'some-esm-native-dep'],
}
optimizeDeps.force
Type: booleanDefault: false

Force re-run of dependency pre-bundling, ignoring the cached result. Use this temporarily when the cache seems stale. Do not commit this to `vite.config.ts` — it slows down dev startup for everyone. Use the CLI flag `vite --force` for a one-time reset instead.

Pitfall:

Committing `optimizeDeps.force: true` to the repo makes cold dev starts slow for every team member. Use `vite --force` on the command line for a one-off re-bundle.

Example
optimizeDeps: {
  force: true,  // ⚠ temporary only, don't commit
}
esbuild
Type: EsbuildOptions | falseDefault: {}

Options passed to esbuild for individual file transforms. `esbuild.jsxInject` auto-imports React so you do not need `import React from "react"` in every file. `esbuild.drop` removes `console` or `debugger` calls in production. Set to `false` to disable esbuild transforms entirely.

Example
esbuild: {
  jsxInject: `import React from 'react'`,
  drop: ['console', 'debugger'],  // prod only
  target: 'es2020',
}
ssr.noExternal
Type: string | RegExp | (string | RegExp)[] | trueDefault: []

Force specified dependencies to be bundled into the SSR output instead of being externalized. Useful for packages that do not ship a valid CJS build or use browser-specific globals that need to be transformed.

Example
ssr: {
  noExternal: ['some-esm-only-package', /^@my-org//],
}

What this tool does

Searchable reference for every important vite.config.ts option, covering six categories you reach for on every project. Server & Preview: server.port, server.host, server.open, server.proxy (with rewrite rules), server.https, server.hmr, server.cors, server.headers, preview.port. Build: build.target, build.outDir, build.assetsDir, build.emptyOutDir, build.minify, build.sourcemap, build.rollupOptions, build.lib, build.cssCodeSplit, build.assetsInlineLimit, build.chunkSizeWarningLimit, build.reportCompressedSize, build.copyPublicDir. Resolve: resolve.alias, resolve.extensions, resolve.conditions, resolve.dedupe. Plugins: plugins array, ordering, framework plugins (React, Vue, Svelte), conditional plugin loading, defineConfig helper with mode/env awareness. CSS: css.modules, css.preprocessorOptions (Sass variables, Less globalVars), css.postcss, css.devSourcemap. Optimizaton: optimizeDeps.include, optimizeDeps.exclude, optimizeDeps.force, ssr.noExternal, esbuild options. Every entry shows the type, default value, bilingual EN/ZH description, a copy-ready vite.config.ts snippet, and a pitfall note where relevant. Search filters across option name, description, snippet, and pitfall. Category chips scope to any single group. 100% client-side, works offline.

Tool details

Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Preview
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
May use a live lookup
A network call is detected in the component, so redact sensitive data when appropriate.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 32 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How Vite Config Cheatsheet fits into your work

Use it in the small gaps between coding, reviewing, debugging, and shipping.

Developer jobs

  • Formatting, validating, shrinking, or inspecting code-adjacent text.
  • Preparing snippets for documentation, tickets, commits, or handoff.
  • Checking a small payload quickly without switching tools.

Developer checks

  • Run irreversible transforms like minify or obfuscate on a copy.
  • Keep secrets out of pasted snippets unless the tool explicitly stays local.
  • Use your normal tests or linter before shipping transformed code.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 TypeScript Config Cheatsheet TypeScript tsconfig.json cheat sheet — 55+ options with defaults, examples, and gotchas. Open
  2. 2 package.json Cheatsheet package.json field reference — 55+ fields explained with real examples, bilingual, searchable. Open
  3. 3 npm / yarn / pnpm Cheatsheet npm / yarn / pnpm cheat sheet — 80+ commands across init, install, scripts, publish, with cross-tool comparison. Open

Real-world use cases

  • Setting up API proxy for a React dev server

    Your React app calls `/api/users` in development, but the Express backend runs on port 3001. You find `server.proxy` in the cheatsheet, copy the snippet with `changeOrigin: true` and `rewrite`, and both servers talk to each other without CORS errors — in under two minutes.

  • Configuring path aliases to clean up deep import chains

    Your codebase has `import Button from '../../../components/Button'` everywhere. You look up `resolve.alias`, copy the snippet, update your tsconfig paths to match, and all your imports become clean `@/components/Button` in one pass.

  • Debugging slow dev startup with pre-bundling

    Your Vite dev server takes 15 seconds to start because it re-bundles a large CommonJS library on every cold start. You find `optimizeDeps.include`, add the offending package, and startup drops to 2 seconds because Vite caches the pre-bundled result.

  • Publishing a library with Vite build.lib

    You want to publish a React component library as an npm package with both ESM and CJS outputs. The cheatsheet shows `build.lib` with `formats: ['es', 'cjs']`, `rollupOptions.external` for peer dependencies (React, ReactDOM), and `build.sourcemap: true` for debuggable published code.

Common pitfalls

  • Forgetting `changeOrigin: true` in server.proxy when the target is a different hostname — the backend rejects the request because the Host header does not match.

  • Setting `resolve.alias` in Vite but not in tsconfig.json paths — Vite resolves files correctly but TypeScript reports "Cannot find module" on every aliased import.

  • Using `optimizeDeps.force: true` in committed config — it forces a full re-bundle on every `vite dev` startup, making cold starts slow for everyone on the team.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-07-01