vite
CLI Toolvitejs/vite
Next generation frontend tooling with instant server start and fast HMR.
Overview
Vite is a build tool that provides a fast dev server with native ES module support and lightning-fast HMR. It offers an optimized production build via Rolldown and a rich plugin system for extensibility.
README Preview
\n \n \n \n \n \n \n \n \n \n \n \n\n\n\n \n \n \n \n \n\n\n\n# Vite ⚡\n\n> Next Generation Frontend Tooling\n\n- 💡 Instant Server Start\n- ⚡️ Lightning Fast HMR\n- 🛠️ Rich Features\n- 📦 Optimized Build\n- 🔩 Universal Plugin Interface\n- 🔑 Fully Typed APIs\n\nVite (French word for "quick", pronounced [`/viːt/`](https://cdn.jsdelivr.net/gh/vitejs/vite@main/docs/public/vite.mp3), like "veet") is a build tool that aims to provide a faster and leaner development experience for modern web projects. It consists of two major parts:\n\n- A dev server that provides [rich feature enhancements](https://vite.dev/guide/features) over [native ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), for example extremely fast [Hot Module Replacement (HMR)](https://vite.dev/guide/features#hot-module-replacement).\n\n- A build command that bundles your code with [Rolldown](https://rolldown.rs), pre-configured to output highly optimized static assets for production.\n\nIn addition, Vite is highly extensible via its [Plugin API](https://vite.dev/guide/api-plugin.html) and [JavaScript API](https://vite.dev/guide/api-javascript.html) with full typing support.\n\n[Read the Docs to Learn More](https://vite.dev).\n\n## Packages\n\n| Package | Version (click for changelogs) |\n| ----------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------- |\n| [vite](packages/vite) | [](packages/vite/CHANGELOG.md) |\n| [@vitejs/plugin-legacy](packages/plugin-legacy) | [](packages/plugin-legacy/CHANGELOG.md) |\n| [create-vite](packages/create-vite) | [](packages/create-vite/CHANGELOG.md) |\n\n## Contributio
FAQ (5)
TroubleshootingWhy does Vite dev server leak memory on repeated server.restart() calls and how to fix it?
Vite 8.x retains retired environments and their module graphs through options.previousEnvironments after each server.restart(), because the server's init/listen closure keeps the options object reachable. This chains across restarts and can retain hundreds of MB of heap, eventually causing Node heap exhaustion. Fix: in _createServer (packages/vite/src/node/server/index.ts), clear the initialization-only reference after the awaited environment initialization completes: options.previousEnvironments = undefined. The previous instance has already been handed to each environment's init by then, so this is safe. Verified on Vite 8.3.0 and 8.1.4 with Node 22/24/26: retired environments drop from 8/8 retained to 0/8. Note there is a separate independent retention bug in Rolldown (#10887) that must also be patched to fully measure the leak.
TroubleshootingHow to fix 'Tsconfig not found' error in Vite 8 dev server with resolve.tsconfigPaths enabled?
This occurs when Vite's dev server uses a synthetic default importer (<root>/index.html) that no tsconfig include matches, causing tsconfig auto-discovery to walk into a parent directory's tsconfig.json whose extends cannot resolve (common in nested git worktrees or React Router framework mode). Workaround: explicitly set the top-level tsconfig option in your Vite config to pin discovery to your project's config:
// vite.config.ts
export default defineConfig({
tsconfig: './tsconfig.json',
resolve: { tsconfigPaths: true },
})
Alternatively, remove or fix the parent directory's tsconfig.json (e.g., install the missing extends package such as @tsconfig/strictest in the parent). The bug affects vite dev and tools calling transformRequest() without an importer, like react-router build/react-router dev.
TroubleshootingHow to fix 'factory.fn is not a function' or "Cannot read properties of undefined (reading 'exports')" error with Vite experimental.bundledDev?
This is a version mismatch: Vite 8.2.4's bundled dev client inlines rolldown 1.2.4's DevRuntime, but rolldown >= 1.2.6 changed dev emission for static imports, so the stale runtime cannot execute the new output. Fix: upgrade Vite to 8.3.5 or later (npm install vite@^8.3.5), which loads the DevRuntime from the installed rolldown so emitter and runtime stay in sync. Workaround if you must stay on Vite 8.2.4: pin rolldown to 1.2.5 (npm install rolldown@1.2.5 or an override in package.json), since 1.2.5's emission still matches the inlined runtime.
TroubleshootingHow to fix Vite not re-bundling dependencies after `yarn install` with Yarn 4 and `nodeLinker: pnpm`?
This happens because Yarn 4 with nodeLinker: pnpm creates neither node_modules/.yarn-state.yml nor .pnp.cjs, so Vite hashes an empty lockfile (lockfileHash: e3b0c442...) and keeps using stale pre-bundled dependencies.
Temporary workarounds:
npx vite --force
Or remove Vite's dependency cache before starting dev:
rm -rf node_modules/.vite/deps && npx vite
For an automated workaround, you can add a postinstall script:
{
"scripts": {
"postinstall": "rm -rf node_modules/.vite/deps"
}
}
Permanent fix: patch Vite's lockfileFormats in packages/vite/src/node/optimizer/index.ts to fall back to the source lockfile, after the existing Yarn entries:
{ path: 'yarn.lock', checkPatchesDir: '.yarn/patches', manager: 'yarn' }
Alternatively, upgrade Vite to a release containing the fix(optimizer): fall back to yarn.lock for lockfile hash change.
TroubleshootingHow to fix Vite dev server crashing with 'EBUSY: resource busy or locked, watch' error on Windows?
Root cause: Vite's dev server subscribes to chokidar's change/add/unlink events but never to error, so any watcher failure (EBUSY from a briefly locked file, EPERM, ENOSPC, exhausted inotify budget) becomes an uncaught exception that kills the whole process. This is much easier to hit on Node 24.16.0+ because libuv 1.52 now opens watched files with read access (a typical trigger: an ASP.NET bin/ folder inside the Vite root, where a freshly compiled DLL is still locked). Workarounds until the core fix ships:
1) Attach your own error handler via a plugin in vite.config.js:
export default {
plugins: [{
name: 'watcher-error-guard',
configureServer(server) {
server.watcher.on('error', (err) => console.error('Watcher error (ignored):', err))
}
}]
}
2) Exclude the locked build output so chokidar never calls fs.watch() on it:
export default { server: { watch: { ignored: ['**/bin/**', '**/obj/**'] } } }
3) Pin Node below 24.16.0 (libuv < 1.52) to avoid the EBUSY trigger from freshly written, still-locked files.
A proper fix (Vite attaching an error listener to the FSWatcher) is being worked on; the upstream libuv regression is tracked at libuv/libuv#5270.