Vite 官方文档
Vite 官方文档。内容保持上游原样。
Blog
Announcing Vite 2.0
February 16, 2021 - Check out the Vite 3.0 announcement
Today we are excited to announce the official release of Vite 2.0!
Vite (French word for "fast", pronounced
/vit/) is a new kind of build tool for frontend web development. Think a pre-configured dev server + bundler combo, but leaner and faster. It leverages browser's native ES modules support and tools written in compile-to-native languages like esbuild to deliver a snappy and modern development experience.
To get a sense of how fast Vite is, check out this video comparison of booting up a React application on Repl.it using Vite vs.
create-react-app (CRA).
If you've never heard of Vite before and would love to learn more about it, check out the rationale behind the project. If you are interested in how Vite differs from other similar tools, check out the comparisons.
What's New in 2.0
Since we decided to completely refactor the internals before 1.0 got out of RC, this is in fact the first stable release of Vite. That said, Vite 2.0 brings about many big improvements over its previous incarnation:
Framework Agnostic Core
The original idea of Vite started as a hacky prototype that serves Vue single-file components over native ESM. Vite 1 was a continuation of that idea with HMR implemented on top.
Vite 2.0 takes what we learned along the way and is redesigned from scratch with a more robust internal architecture. It is now completely framework agnostic, and all framework-specific support is delegated to plugins. There are now official templates for Vue, React, Preact, Lit Element, and ongoing community efforts for Svelte integration.
New Plugin Format and API
Inspired by WMR, the new plugin system extends Rollup's plugin interface and is compatible with many Rollup plugins out of the box. Plugins can use Rollup-compatible hooks, with additional Vite-specific hooks and properties to adjust Vite-only behavior (e.g. differentiating dev vs. build or custom handling of HMR).
The programmatic API has also been greatly improved to facilitate higher level tools / frameworks built on top of Vite.
esbuild Powered Dep Pre-Bundling
Since Vite is a native ESM dev server, it pre-bundles dependencies to reduce the number browser requests and handle CommonJS to ESM conversion. Previously Vite did this using Rollup, and in 2.0 it now uses
esbuild which results in 10-100x faster dependency pre-bundling. As a reference, cold-booting a test app with heavy dependencies like React Material UI previously took 28 seconds on an M1-powered MacBook Pro and now takes ~1.5 seconds. Expect similar improvements if you are switching from a traditional bundler based setup.
First-class CSS Support
Vite treats CSS as a first-class citizen of the module graph and supports the following out of the box:
Resolver enhancement:
@import and
url() paths in CSS are enhanced with Vite's resolver to respect aliases and npm dependencies.
URL rebasing:
url() paths are automatically rebased regardless of where the file is imported from.
CSS code splitting: a code-split JS chunk also emits a corresponding CSS file, which is automatically loaded in parallel with the JS chunk when requested.
Server-Side Rendering (SSR) Support
Vite 2.0 ships with experimental SSR support. Vite provides APIs to efficiently load and update ESM-based source code in Node.js during development (almost like server-side HMR), and automatically externalizes CommonJS-compatible dependencies to improve development and SSR build speed. The production server can be completely decoupled from Vite, and the same setup can be easily adapted to perform pre-rendering / SSG.
Vite SSR is provided as a low-level feature and we are expecting to see higher level frameworks leveraging it under the hood.
Opt-in Legacy Browser Support
Vite targets modern browsers with native ESM support by default, but you can also opt-in to support legacy browsers via the official @vitejs/plugin-legacy. The plugin automatically generates dual modern/legacy bundles, and delivers the right bundle based on browser feature detection, ensuring more efficient code in modern browsers that support them.
Give it a Try!
That was a lot of features, but getting started with Vite is simple! You can spin up a Vite-powered app literally in a minute, starting with the following command (make sure you have Node.js >=12):
npm init @vitejs/app
Then, check out the guide to see what Vite provides out of the box. You can also check out the source code on GitHub, follow updates on Twitter, or join discussions with other Vite users on our Discord chat server.
Vite 3.0 is out!
July 23, 2022 - Check out the Vite 4.0 announcement
In February last year, Evan You released Vite 2. Since then, its adoption has grown non-stop, reaching more than 1 million npm downloads per week. A sprawling ecosystem rapidly formed after the release. Vite is powering a renewed innovation race in Web frameworks. Nuxt 3 uses Vite by default. SvelteKit, Astro, Hydrogen, and SolidStart are all built with Vite. Laravel has now decided to use Vite by default. Vite Ruby shows how Vite can improve Rails DX. Vitest is making strides as a Vite-native alternative to Jest. Vite is behind Cypress and Playwright's new Component Testing features, Storybook has Vite as an official builder. And the list goes on. Maintainers from most of these projects got involved in improving the Vite core itself, working closely with the Vite team and other contributors.
Today, 16 months from the v2 launch we are happy to announce the release of Vite 3. We decided to release a new Vite major at least every year to align with Node.js's EOL, and take the opportunity to review Vite's API regularly with a short migration path for projects in the ecosystem.
Quick links:
Docs
Migration Guide
Changelog
If you are new to Vite, we recommend reading the Why Vite Guide. Then check out the Getting Started and Features guide to see what Vite provides out of the box. As usual, contributions are welcome at GitHub. More than 600 collaborators have helped improve Vite so far. Follow the updates on Twitter, or join discussions with other Vite users on our Discord chat server.
New Documentation
Go to vite.dev to enjoy the new v3 docs. Vite is now using the new VitePress default theme, with a stunning dark mode between other features.
Several projects in the ecosystem have already migrated to it (see Vitest, vite-plugin-pwa, and VitePress itself).
If you need to access the Vite 2 docs, they will remain online at v2.vite.dev. There is also a new main.vite.dev subdomain, where each commit to Vite’s main branch is auto deployed. This is useful when testing beta versions or contributing to the core’s development.
There is also now an official Spanish translation, that has been added to the previous Chinese and Japanese translations:
简体中文
日本語
Español
Create Vite Starter Templates
create-vite templates have been a great tool to quickly test Vite with your favorite framework. In Vite 3, all of the templates got a new theme in line with the new docs. Open them online and start playing with Vite 3 now:
The theme is now shared by all templates. This should help better convey the scope for these starters as minimal templates to get started with Vite. For more complete solutions including linting, testing setup, and other features, there are official Vite-powered templates for some frameworks like create-vue and create-svelte. There is a community-maintained list of templates at Awesome Vite.
Dev Improvements
Vite CLI
VITE v3.0.0 ready in 320 ms
➜ Local: http://127.0.0.1:5173/
➜ Network: use --host to expose
Apart from the CLI’s aesthetics improvements, you’ll notice that the default dev server port is now 5173 and the preview server listening at 4173. This change ensures Vite will avoid collisions with other tools.
Improved WebSocket Connection Strategy
One of the pain points of Vite 2 was configuring the server when running behind a proxy. Vite 3 changes the default connection scheme so it works out of the box in most scenarios. All these setups are now tested as part of the Vite Ecosystem CI through
vite-setup-catalogue.
Cold Start Improvements
Vite now avoids full reload during cold start when imports are injected by plugins while crawling the initial statically imported modules (#8869).
Click to learn more
In Vite 2.9, both the scanner and optimizer were run in the background. In the best scenario, where the scanner would find every dependency, no reload was needed in cold start. But if the scanner missed a dependency, a new optimization phase and then a reload were needed. Vite was able to avoid some of these reloads in v2.9, as we detected if the new optimized chunks were compatible with the ones the browser had. But if there was a common dep, the sub-chunks could change and a reload was required to avoid duplicated state. In Vite 3, the optimized deps aren't handed to the browser until the crawling of static imports is done. A quick optimization phase is issued if there is a missing dep (for example, injected by a plugin), and only then, the bundled deps are sent. So, a page reload is no longer needed for these cases.
import.meta.glob
import.meta.glob support was rewritten. Read about the new features in the Glob Import Guide:
Multiple Patterns can be passed as an array
import.meta.glob(['./dir/*.js', './another/*.js'])
Negative Patterns are now supported (prefixed with
!) to ignore some specific files
import.meta.glob(['./dir/*.js', '!**/bar.js'])
Named Imports can be specified to improve tree-shaking
import.meta.glob('./dir/*.js', { import: 'setup' })
Custom Queries can be passed to attach metadata
import.meta.glob('./dir/*.js', { query: { custom: 'data' } })
Eager Imports is now passed as a flag
import.meta.glob('./dir/*.js', { eager: true })
Aligning WASM Import with Future Standards
The WebAssembly import API has been revised to avoid collisions with future standards and to make it more flexible:
import init from './example.wasm?init'
init().then((instance) => {
instance.exports.test()
})
Learn more in the WebAssembly guide
Build Improvements
ESM SSR Build by Default
Most SSR frameworks in the ecosystem were already using ESM builds. So, Vite 3 makes ESM the default format for SSR builds. This allows us to streamline previous SSR externalization heuristics, externalizing dependencies by default.
Improved Relative Base Support
Vite 3 now properly supports relative base (using
base: ''), allowing built assets to be deployed to different bases without re-building. This is useful when the base isn't known at build time, for example when deploying to content-addressable networks like IPFS.
Experimental Features
Built Asset Paths fine-grained Control (Experimental)
There are other deploy scenarios where this isn't enough. For example, if the generated hashed assets need to be deployed to a different CDN from the public files, then finer-grained control is required over path generation at build time. Vite 3 provides an experimental API to modify the built file paths. Check Build Advanced Base Options for more information.
Esbuild Deps Optimization at Build Time (Experimental)
One of the main differences between dev and build time is how Vite handles dependencies. During build time,
@rollup/plugin-commonjs is used to allow importing CJS only dependencies (like React). When using the dev server, esbuild is used instead to pre-bundle and optimize dependencies, and an inline interop scheme is applied while transforming user code importing CJS deps. During the development of Vite 3, we introduced the changes needed to also allow the use of esbuild to optimize dependencies during build time.
@rollup/plugin-commonjs can then be avoided, making dev and build time work in the same way.
Given that Rollup v3 will be out in the next months, and we're going to follow up with another Vite major, we've decided to make this mode optional to reduce v3 scope and give Vite and the ecosystem more time to work out possible issues with the new CJS interop approach during build time. Frameworks may switch to using esbuild deps optimization during build time by default at their own pace before Vite 4.
HMR Partial Accept (Experimental)
There is opt-in support for HMR Partial Accept. This feature could unlock finer-grained HMR for framework components that export several bindings in the same module. You can learn more at the discussion for this proposal.
Bundle Size Reduction
Vite cares about its publish and install footprint; a fast installation of a new app is a feature. Vite bundles most of its dependencies and tries to use modern lightweight alternatives where possible. Continuing with this ongoing goal, Vite 3 publish size is 30% smaller than v2.
Publish Size
Install Size
Vite 2.9.14
4.38MB
19.1MB
Vite 3.0.0
3.05MB
17.8MB
Reduction
-30%
-7%
In part, this reduction was possible by making some dependencies that most users weren't needing optional. First, Terser is no longer installed by default. This dependency was no longer needed since we already made esbuild the default minifier for both JS and CSS in Vite 2. If you use
build.minify: 'terser', you'll need to install it (
npm add -D terser). We also moved node-forge out of the monorepo, implementing support for automatic https certificate generation as a new plugin:
@vitejs/plugin-basic-ssl. Since this feature only creates untrusted certificates that are not added to the local store, it didn't justify the added size.
Bug Fixing
A triaging marathon was spearheaded by @bluwyoo, @sapphi_red, that recently joined the Vite team. During the past three months, the Vite open issues were reduced from 770 to 400. And this dive was achieved while the newly open PRs were at an all-time high. At the same time, @haoqunjiang had also curated a comprehensive overview of Vite issues.
Compatibility Notes
Vite no longer supports Node.js 12 / 13 / 15, which reached its EOL. Node.js 14.18+ / 16+ is now required.
Vite is now published as ESM, with a CJS proxy to the ESM entry for compatibility.
The Modern Browser Baseline now targets browsers which support the native ES Modules, native ESM dynamic import, and
import.meta features.
JS file extensions in SSR and library mode now use a valid extension (
js,
mjs, or
cjs) for output JS entries and chunks based on their format and the package type.
Learn more in the Migration Guide.
Upgrades to Vite Core
While working towards Vite 3, we also improved the contributing experience for collaborators to Vite Core.
Unit and E2E tests have been migrated to Vitest, providing a faster and more stable DX. This move also works as dog fooding for an important infrastructure project in the ecosystem.
VitePress build is now tested as part of CI.
Vite upgraded to pnpm 7, following the rest of the ecosystem.
Playgrounds have been moved to
/playgrounds out of packages directory.
The packages and playgrounds are now
"type": "module".
Plugins are now bundled using unbuild, and plugin-vue-jsx and plugin-legacy were moved to TypeScript.
The Ecosystem is Ready for v3
We have worked closely with projects in the ecosystem to ensure that frameworks powered by Vite are ready for Vite 3. vite-ecosystem-ci allows us to run the CI's from the leading players in the ecosystem against Vite's main branch and receive timely reports before introducing a regression. Today's release should soon be compatible with most projects using Vite.
Acknowledgments
Vite 3 is the result of the aggregate effort of members of the Vite Team working together with ecosystem project maintainers and other collaborators to Vite core.
We want to thank everyone who has implemented features, and fixes, given feedback, and have been involved in Vite 3:
Vite team members @youyuxi, @patak_dev, @antfu7, @bluwyoo, @sapphi_red, @haoqunjiang, @poyoho, @Shini_92, and @retropragma.
@benmccann, @danielcroe, @brillout, @sheremet_va, @userquin, @enzoinnocenzi, @maximomussini, @IanVanSchooten, the Astro team, and all other maintainers of frameworks and plugins in the ecosystem in that helped shape v3.
@dominikg for his work on vite-ecosystem-ci.
@ZoltanKochan for his work on pnpm, and for his responsiveness when we needed support with it.
@rixo for HMR Partial Accept support.
@KiaKing85 for getting the theme ready for the Vite 3 release, and @_brc_dd for working on the VitePress internals.
@CodingWithCego for the new Spanish translation, and @ShenQingchuan, @hiro-lapis and others in the Chinese and Japanese translations teams for keeping the translated docs up to date.
We also want to thank individuals and companies sponsoring the Vite team, and companies investing in Vite development: some of @antfu7's work on Vite and the ecosystem is part of his job at Nuxt Labs, and StackBlitz hired @patak_dev to work full time on Vite.
What's Next
We'll take the following months to ensure a smooth transition for all the projects built on top of Vite. So the first minors will be focused on continuing our triaging efforts with a focus on newly opened issues.
The Rollup team is working on its next major, to be released in the following months. Once the Rollup plugins ecosystem has time to update, we'll follow up with a new Vite major. This will give us another opportunity to introduce more significant changes this year, which we could take to stabilize some of the experimental features introduced in this release.
If you are interested in helping improve Vite, the best way to get on board is to help with triaging issues. Join our Discord and look for the
#contributing channel. Or get involved in our
#docs,
#help others, or create plugins. We are just getting started. There are many open ideas to keep improving Vite's DX.
Vite 4.3 is out!
April 20, 2023
Quick links:
Docs: English, 简体中文, 日本語, Español, Português
Vite 4.3 Changelog
Performance Improvements
In this minor, we focused on improving the dev server performance. The resolve logic got streamlined, improving hot paths and implementing smarter caching for finding
package.json, TS config files, and resolved URL in general.
You can read a detailed walkthrough of the performance work done in this blog post by one of Vite Contributors: How we made Vite 4.3 faaaaster 🚀.
This sprint resulted in speed improvements across the board compared to Vite 4.2.
These are the performance improvements as measured by sapphi-red/performance-compare, which tests an app with 1000 React Components cold and warm dev server startup time as well as HMR times for a root and a leaf component:
Vite (babel)
Vite 4.2
Vite 4.3
Improvement
dev cold start
17249.0ms
5132.4ms
-70.2%
dev warm start
6027.8ms
4536.1ms
-24.7%
Root HMR
46.8ms
26.7ms
-42.9%
Leaf HMR
27.0ms
12.9ms
-52.2%
Vite (swc)
Vite 4.2
Vite 4.3
Improvement
dev cold start
13552.5ms
3201.0ms
-76.4%
dev warm start
4625.5ms
2834.4ms
-38.7%
Root HMR
30.5ms
24.0ms
-21.3%
Leaf HMR
16.9ms
10.0ms
-40.8%
You can read more information about the benchmark here. Specs and Versions for this performance run:
CPU: Ryzen 9 5900X, Memory: DDR4-3600 32GB, SSD: WD Blue SN550 NVME SSD
Windows 10 Pro 21H2 19044.2846
Node.js 18.16.0
Vite and React Plugin versions
Vite 4.2 (babel): Vite 4.2.1 + plugin-react 3.1.0
Vite 4.3 (babel): Vite 4.3.0 + plugin-react 4.0.0-beta.1
Vite 4.2 (swc): Vite 4.2.1 + plugin-react-swc 3.2.0
Vite 4.3 (swc): Vite 4.3.0 + plugin-react-swc 3.3.0
Early adopters have also reported seeing 1.5x-2x dev startup time improvement on real apps while testing the Vite 4.3 beta. We'd love to know the results for your apps.
Profiling
We'll continue to work on Vite's performance. We're working on an official Benchmark tool for Vite that let us get performance metrics for each Pull Request.
And vite-plugin-inspect now has more performance-related features to help you identify which plugins or middlewares are the bottleneck for your applications.
Using
vite --profile (and then pressing
p) once the page loads will save a CPU profile of the dev server startup. You can open them in an app as speedscope to identify performance issues. And you can share your findings with the Vite Team in a Discussion or in Vite's Discord.
Next Steps
We decided to do a single Vite Major this year aligning with the EOL of Node.js 16 in September, dropping support for both Node.js 14 and 16 in it. If you would like to get involved, we started a Vite 5 Discussion to gather early feedback.
Vite 4.0 is out!
December 9, 2022 - Check out the Vite 5.0 announcement
Vite 3 was released five months ago. npm downloads per week have gone from 1 million to 2.5 million since then. The ecosystem has matured too, and continues to grow. In this year's Jamstack Conf survey, usage among the community jumped from 14% to 32% while keeping a high 9.7 satisfaction score. We saw the stable releases of Astro 1.0, Nuxt 3, and other Vite-powered frameworks that are innovating and collaborating: SvelteKit, Solid Start, Qwik City. Storybook announced first-class support for Vite as one of its main features for Storybook 7.0. Deno now supports Vite. Vitest adoption is exploding, it will soon represent half of Vite's npm downloads. Nx is also investing in the ecosystem, and officially supports Vite.
As a showcase of the growth Vite and related projects have experienced, the Vite ecosystem gathered on October 11th at ViteConf 2022. We saw representatives from the main web framework and tools tell stories of innovation and collaboration. And in a symbolic move, the Rollup team choose that exact day to release Rollup 3.
Today, the Vite team with the help of our ecosystem partners, is happy to announce the release of Vite 4, powered during build time by Rollup 3. We've worked with the ecosystem to ensure a smooth upgrade path for this new major. Vite is now using Rollup 3, which allowed us to simplify Vite's internal asset handling and has many improvements. See the Rollup 3 release notes here.
Quick links:
Docs
Migration Guide
Changelog
Docs in other languages:
简体中文
日本語
Español
If you recently started using Vite, we suggest reading the Why Vite Guide and checking out the Getting Started and Features guide. If you want to get involved, contributions are welcome at GitHub. Almost 700 collaborators have contributed to Vite. Follow the updates on Twitter and Mastodon, or collaborate with others on our Discord community.
Start playing with Vite 4
Use
pnpm create vite to scaffold a Vite project with your preferred framework, or open a started template online to play with Vite 4 using vite.new.
You can also run
pnpm create vite-extra to get access to templates from other frameworks and runtimes (Solid, Deno, SSR, and library starters).
create vite-extra templates are also available when you run
create vite under the
Others option.
Note that Vite starter templates are intended to be used as a playground to test Vite with different frameworks. When building your next project, we recommend reaching out to the starters recommended by each framework. Some frameworks now redirect in
create vite to their starters too (
create-vue and
Nuxt 3 for Vue, and
SvelteKit for Svelte).
New React plugin using SWC during development
SWC is now a mature replacement for Babel, especially in the context of React projects. SWC's React Fast Refresh implementation is a lot faster than Babel, and for some projects, it is now a better alternative. From Vite 4, two plugins are available for React projects with different tradeoffs. We believe that both approaches are worth supporting at this point, and we'll continue to explore improvements to both plugins in the future.
@vitejs/plugin-react
@vitejs/plugin-react is a plugin that uses esbuild and Babel, achieving fast HMR with a small package footprint and the flexibility of being able to use the Babel transform pipeline.
@vitejs/plugin-react-swc (new)
@vitejs/plugin-react-swc is a new plugin that uses esbuild during build, but replaces Babel with SWC during development. For big projects that don't require non-standard React extensions, cold start and Hot Module Replacement (HMR) can be significantly faster.
Browser Compatibility
The modern browser build now targets
safari14 by default for wider ES2020 compatibility. This means that modern builds can now use
BigInt and that the nullish coalescing operator isn't transpiled anymore. If you need to support older browsers, you can add
@vitejs/plugin-legacy as usual.
Importing CSS as a String
In Vite 3, importing the default export of a
.css file could introduce a double loading of CSS.
import cssString from './global.css'
This double loading could occur since a
.css file will be emitted and it's likely that the CSS string will also be used by the application code — for example, injected by the framework runtime. From Vite 4, the
.css default export has been deprecated. The
?inline query suffix modifier needs to be used in this case, as that doesn't emit the imported
.css styles.
import stuff from './global.css?inline'
Learn more in the Migration Guide.
Environment Variables
Vite now uses
dotenv 16 and
dotenv-expand 9 (previously
dotenv 14 and
dotenv-expand 5). If you have a value including
# or
`, you will need to wrap them with quotes.
-VITE_APP=ab#cd`ef
+VITE_APP="ab#cd`ef"
For more details, see the
dotenv and
dotenv-expand changelog.
Other Features
CLI Shortcuts (press
h during dev to see them all) (#11228)
Support for patch-package when pre bundling dependencies (#10286)
Cleaner build logs output (#10895) and switch to
kB to align with browser dev tools (#10982)
Improved error messages during SSR (#11156)
Reduced Package Size
Vite cares about its footprint, to speed up installation, especially in the use case of playgrounds for documentation and reproductions. And once more, this major brings improvements in Vite's package size. Vite 4 install size is 23% smaller compared to vite 3.2.5 (14.1 MB vs 18.3 MB).
Upgrades to Vite Core
Vite Core and vite-ecosystem-ci continue to evolve to provide a better experience to maintainers and collaborators and to ensure that Vite development scales to cope with the growth in the ecosystem.
Framework plugins out of core
@vitejs/plugin-vue and
@vitejs/plugin-react have been part of Vite core monorepo since the first versions of Vite. This helped us to get a close feedback loop when making changes as we were getting both Core and the plugins tested and released together. With vite-ecosystem-ci we can get this feedback with these plugins developed on independent repositories, so from Vite 4, they have been moved out of the Vite core monorepo. This is meaningful for Vite's framework-agnostic story and will allow us to build independent teams to maintain each of the plugins. If you have bugs to report or features to request, please create issues on the new repositories moving forward:
vitejs/vite-plugin-vue and
vitejs/vite-plugin-react.
vite-ecosystem-ci improvements
vite-ecosystem-ci extends Vite's CI by providing on-demand status reports on the state of the CIs of most major downstream projects. We run vite-ecosystem-ci three times a week against Vite's main branch and receive timely reports before introducing a regression. Vite 4 will soon be compatible with most projects using Vite, which already prepared branches with the needed changes and will be releasing them in the next few days. We are also able to run vite-ecosystem-ci on-demand on PRs using
/ecosystem-ci run in a comment, allowing us to know the effect of changes before they hit main.
Acknowledgments
Vite 4 wouldn't be possible without uncountable hours of work by Vite contributors, many of them maintainers of downstream projects and plugins, and the efforts of the Vite Team. All of us have worked together to improve Vite's DX once more, for every framework and app using it. We're grateful to be able to improve a common base for such a vibrant ecosystem.
We're also thankful to individuals and companies sponsoring the Vite team, and companies investing directly in Vite's future: @antfu7's work on Vite and the ecosystem is part of his job at Nuxt Labs, Astro is funding @bluwyoo's Vite core work, and StackBlitz hires @patak_dev to work full time on Vite.
Next steps
Our immediate focus would be on triaging newly opened issues to avoid disruption by possible regressions. If you would like to get involved and help us improve Vite, we suggest starting with issues triaging. Join our Discord and reach out on the
#contributing channel. Polish our
#docs story, and
#help others. We need to continue to build a helpful and welcoming community for the next wave of users, as Vite's adoption continues to grow.
There are a lot of open fronts to keep improving the DX of everyone that has chosen Vite to power their frameworks and develop their apps. Onwards!
Vite 5.1 is out!
February 8, 2024
Vite 5 was released last November, and it represented another big leap for Vite and the ecosystem. A few weeks ago we celebrated 10 million weekly npm downloads and 900 contributors to the Vite repo. Today, we're excited to announce the release of Vite 5.1.
Quick links: Docs, Changelog
Docs in other languages: 简体中文, 日本語, Español, Português, 한국어, Deutsch
Try Vite 5.1 online in StackBlitz: vanilla, vue, react, preact, lit, svelte, solid, qwik.
If you're new to Vite, we suggest reading first the Getting Started and Features guides.
To stay up to date, follow us on X or Mastodon.
Vite Runtime API
Vite 5.1 adds experimental support for a new Vite Runtime API. It allows running any code by processing it with Vite plugins first. It is different from
server.ssrLoadModule because the runtime implementation is decoupled from the server. This lets library and framework authors implement their own layer of communication between the server and the runtime. This new API is intended to replace Vite's current SSR primitives once it is stable.
The new API brings many benefits:
Support for HMR during SSR.
It is decoupled from the server, so there is no limit on how many clients can use a single server - every client has its own module cache (you can even communicate with it how you want - using message channel/fetch call/direct function call/websocket).
It doesn't depend on any node/bun/deno built-in APIs, so it can run in any environment.
It's easy to integrate with tools that have their own mechanism to run code (you can provide a runner to use
eval instead of
new AsyncFunction for example).
The initial idea was proposed by Pooya Parsa and implemented by Anthony Fu as the vite-node package to power Nuxt 3 Dev SSR and later also used as the base for Vitest. So the general idea of vite-node has been battle-tested for quite some time now. This is a new iteration of the API by Vladimir Sheremet, who had already re-implemented vite-node in Vitest and took the learnings to make the API even more powerful and flexible when adding it to Vite Core. The PR was one year in the makings, you can see the evolution and discussions with ecosystem maintainers here.
::: info
The Vite Runtime API evolved into the Module Runner API, released in Vite 6 as part of the Environment API.
:::
Features
Improved support for
.css?url
Import CSS files as URLs now works reliably and correctly. This was the last remaining hurdle in Remix's move to Vite. See (#15259).
build.assetsInlineLimit now supports a callback
Users can now provide a callback that returns a boolean to opt-in or opt-out of inlining for specific assets. If
undefined is returned, the default logic applies. See (#15366).
Improved HMR for circular import
In Vite 5.0, accepted modules within circular imports always triggered a full page reload even if they can be handled fine in the client. This is now relaxed to allow HMR to apply without a full page reload, but if any error happens during HMR, the page will be reloaded. See (#15118).
Support
ssr.external: true to externalize all SSR packages
Historically, Vite externalizes all packages except for linked packages. This new option can be used to force externalize all packages including linked packages too. This is handy in tests within monorepos where we want to emulate the usual case of all packages externalized, or when using
ssrLoadModule to load an arbitrary file and we want to always external packages as we don't care about HMR. See (#10939).
Expose
close method in the preview server
The preview server now exposes a
close method, which will properly teardown the server including all opened socket connections. See (#15630).
Performance improvements
Vite keeps getting faster with each release, and Vite 5.1 is packed with performance improvements. We measured the loading time for 10K modules (25 level deep tree) using vite-dev-server-perf for all minor versions from Vite 4.0. This is a good benchmark to measure the effect of Vite's bundle-less approach. Each module is a small TypeScript file with a counter and imports to other files in the tree, so this mostly measures the time it takes to do the requests as separate modules. In Vite 4.0, loading 10K modules took 8 seconds on a M1 MAX. We had a breakthrough in Vite 4.3 where we focused on performance, and we were able to load them in 6.35 seconds. In Vite 5.1, we managed to do another performance leap. Vite is now serving the 10K modules in 5.35 seconds.
The results of this benchmark run on Headless Puppeteer and are a good way to compare versions. They don't represent the time as experienced by users though. When running the same 10K modules in an Incognito window in Chrome, we have:
10K Modules
Vite 5.0
Vite 5.1
Loading time
2892ms
2765ms
Loading time (cached)
2778ms
2477ms
Full reload
2003ms
1878ms
Full reload (cached)
1682ms
1604ms
Run CSS preprocessors in threads
Vite now has opt-in support for running CSS preprocessors in threads. You can enable it using
css.preprocessorMaxWorkers: true. For a Vuetify 2 project, dev startup time was reduced by 40% with this feature enabled. There is performance comparison for others setups in the PR. See (#13584). Give Feedback.
New options to improve server cold starts
You can set
optimizeDeps.holdUntilCrawlEnd: false to switch to a new strategy for deps optimization that may help in big projects. We're considering switching to this strategy by default in the future. Give Feedback. (#15244)
Faster resolving with cached checks
The
fs.cachedChecks optimization is now enabled by default. In Windows,
tryFsResolve was ~14x faster with it, and resolving ids overall got a ~5x speed up in the triangle benchmark. (#15704)
Internal performance improvements
The dev server had several incremental performance gains. A new middleware to short-circuit on 304 (#15586). We avoided
parseRequest in hot paths (#15617). Rollup is now properly lazy loaded (#15621)
Deprecations
We continue to reduce Vite's API surface where possible to make the project maintainable long term.
Deprecated
as option in
import.meta.glob
The standard moved to Import Attributes, but we don't plan to replace
as with a new option at this point. Instead, it is recommended that the user switches to
query. See (#14420).
Removed experimental build-time pre-bundling
Build-time pre-bundling, an experimental feature added in Vite 3, is removed. With Rollup 4 switching its parser to native, and Rolldown being worked on, both the performance and the dev-vs-build inconsistency story for this feature are no longer valid. We want to continue improving dev/build consistency, and have concluded that using Rolldown for "prebundling during dev" and "production builds" is the better bet moving forward. Rolldown may also implement caching in a way that is a lot more efficient during build than deps prebundling. See (#15184).
Get Involved
We are grateful to the 900 contributors to Vite Core, and the maintainers of plugins, integrations, tools, and translations that keeps pushing the ecosystem forward. If you're enjoying Vite, we invite you to participate and help us. Check out our Contributing Guide, and jump into triaging issues, reviewing PRs, answering questions at GitHub Discussions and helping others in the community in Vite Land.
Acknowledgments
Vite 5.1 is possible thanks to our community of contributors, maintainers in the ecosystem, and the Vite Team. A shout out to the individuals and companies sponsoring Vite development. StackBlitz, Nuxt Labs, and Astro for hiring Vite team members. And also to the sponsors on Vite's GitHub Sponsors, Vite's Open Collective, and Evan You's GitHub Sponsors.
Vite 5.0 is out!
November 16, 2023
Vite 4 was released almost a year ago, and it served as a solid base for the ecosystem. npm downloads per week jumped from 2.5 million to 7.5 million, as projects keep building on a shared infrastructure. Frameworks continued to innovate, and on top of Astro, Nuxt, SvelteKit, Solid Start, Qwik City, between others, we saw new frameworks joining and making the ecosystem stronger. RedwoodJS and Remix switching to Vite paves the way for further adoption in the React ecosystem. Vitest kept growing at an even faster pace than Vite. Its team has been hard at work and will soon release Vitest 1.0. The story of Vite when used with other tools such as Storybook, Nx, and Playwright kept improving, and the same goes for environments, with Vite dev working both in Deno and Bun.
We had the second edition of ViteConf a month ago, hosted by StackBlitz. Like last year, most of the projects in the ecosystem got together to share ideas and connect to keep expanding the commons. We're also seeing new pieces complement the meta-framework tool belt like Volar and Nitro. The Rollup team released Rollup 4 that same day, a tradition Lukas started last year.
Six months ago, Vite 4.3 was released. This release significantly improved the dev server performance. However, there is still ample room for improvement. At ViteConf, Evan You unveiled Vite's long-term plan to work on Rolldown, a Rust-port of Rollup with compatible APIs. Once it is ready, we intend to use it in Vite Core to take on the tasks of both Rollup and esbuild. This will mean a boost in build performance (and later on in dev performance too as we move perf-sensitive parts of Vite itself to Rust), and a big reduction of inconsistencies between dev and build. Rolldown is currently in early stages and the team is preparing to open source the codebase before the end of the year. Stay tuned!
Today, we mark another big milestone in Vite's path. The Vite team, contributors, and ecosystem partners, are excited to announce the release of Vite 5. Vite is now using Rollup 4, which already represents a big boost in build performance. And there are also new options to improve your dev server performance profile.
Vite 5 focuses on cleaning up the API (removing deprecated features) and streamlines several features closing long-standing issues, for example switching
define to use proper AST replacements instead of regexes. We also continue to take steps to future-proof Vite (Node.js 18+ is now required, and the CJS Node API has been deprecated).
Quick links:
Docs
Migration Guide
Changelog
Docs in other languages:
简体中文
日本語
Español
Português
한국어
Deutsch (new translation!)
If you're new to Vite, we suggest reading first the Getting Started and Features guides.
We appreciate the more than 850 contributors to Vite Core, and the maintainers and contributors of Vite plugins, integrations, tools, and translations that have helped us reach here. We encourage you to get involved and continue to improve Vite with us. You can learn more at our Contributing Guide. To get started, we recommend triaging issues, reviewing PRs, sending failing tests PRs based on open issues, and helping others in Discussions and Vite Land's help forum. You'll learn a lot along the way and have a smooth path to further contributions to the project. If you have doubts, join us on our Discord community and say hi on the #contributing channel.
To stay up to date, follow us on X or Mastodon.
Quick start with Vite 5
Use
pnpm create vite to scaffold a Vite project with your preferred framework, or open a started template online to play with Vite 5 using vite.new. You can also run
pnpm create vite-extra to get access to templates from other frameworks and runtimes (Solid, Deno, SSR, and library starters).
create vite-extra templates are also available when you run
create vite under the
Others option.
Note that Vite starter templates are intended to be used as a playground to test Vite with different frameworks. When building your next project, we recommend reaching out to the starters recommended by each framework. Some frameworks now redirect in
create vite to their starters too (
create-vue and
Nuxt 3 for Vue, and
SvelteKit for Svelte).
Node.js Support
Vite no longer supports Node.js 14 / 16 / 17 / 19, which reached its EOL. Node.js 18 / 20+ is now required.
Performance
On top of Rollup 4's build performance improvements, there is a new guide to help you identify and fix common performance issues at https://vite.dev/guide/performance.
Vite 5 also introduces server.warmup, a new feature to improve startup time. It lets you define a list of modules that should be pre-transformed as soon as the server starts. When using
--open or
server.open, Vite will also automatically warm up the entry point of your app or the provided URL to open.
Main Changes
Vite is now powered by Rollup 4
The CJS Node API has been deprecated
Rework
define and
import.meta.env.* replacement strategy
SSR externalized modules value now matches production
worker.plugins is now a function
Allow path containing
. to fallback to index.html
Align dev and preview HTML serving behavior
Manifest files are now generated in
.vite directory by default
CLI shortcuts require an additional
Enter press
Update
experimentalDecorators and
useDefineForClassFields TypeScript behavior
Remove
--https flag and
https: true
Remove
resolvePackageEntry and
resolvePackageData APIs
Removes previously deprecated APIs
Read more about advanced changes affecting plugin and tool authors
Migrating to Vite 5
We have worked with ecosystem partners to ensure a smooth migration to this new major. Once again, vite-ecosystem-ci has been crucial to help us make bolder changes while avoiding regressions. We're thrilled to see other ecosystems adopt similar schemes to improve the collaboration between their projects and downstream maintainers.
For most projects, the update to Vite 5 should be straight forward. But we advise reviewing the detailed Migration Guide before upgrading.
A low level breakdown with the full list of changes to Vite core can be found at the Vite 5 Changelog.
Acknowledgments
Vite 5 is the result of long hours of work by our community of contributors, downstream maintainers, plugins authors, and the Vite Team. A big shout out to Bjorn Lu for leading the release process for this major.
We're also thankful to individuals and companies sponsoring Vite development. StackBlitz, Nuxt Labs, and Astro continue to invest in Vite by hiring Vite team members. A shout out to sponsors on Vite's GitHub Sponsors, Vite's Open Collective, and Evan You's GitHub Sponsors. A special mention to Remix for becoming a Gold sponsor and contributing back after switching to Vite.
Vite 6.0 is out!
November 26, 2024
Today, we're taking another big step in Vite's story. The Vite team, contributors, and ecosystem partners are excited to announce the release of Vite 6.
It has been an eventful year. Vite adoption keeps growing, with npm downloads per week jumping from 7.5 million to 17 million since the release of Vite 5 a year ago. Vitest is not only being favored more by users but is also starting to form an ecosystem of its own. For example, Storybook has new testing capabilities powered by Vitest.
New frameworks have also joined the Vite ecosystem, including TanStack Start, One, Ember, and others. Web frameworks are innovating at an increasingly faster pace. You can check out the improvements folks have been doing at Astro, Nuxt, SvelteKit, Solid Start, Qwik City, RedwoodJS, React Router, and the list goes on.
Vite is used by OpenAI, Google, Apple, Microsoft, NASA, Shopify, Cloudflare, GitLab, Reddit, Linear, among many others. Two months ago, we started a list of companies using Vite. We're happy to see many developers sending us a PR to add their companies to the list. It's hard to believe how much the ecosystem we built together has grown since Vite gave its first steps.
Speeding up the Vite ecosystem
Last month, the community gathered for the third edition of ViteConf, hosted once more by StackBlitz. It was the biggest Vite conference, with a broad representation of builders from the ecosystem. Among other announcements, Evan You announced VoidZero, a company dedicated to building an open-source, high-performance, and unified development toolchain for the JavaScript ecosystem. VoidZero is behind Rolldown and Oxc, and their team is making significant strides, getting them rapidly ready for being adopted by Vite. Watch Evan's keynote to learn more about the next steps for Vite's rust-powered future.
Stackblitz unveiled bolt.new, a Remix app that combines Claude and WebContainers and lets you prompt, edit, run, and deploy full-stack apps. Nate Weiner announced One, a new Vite-powered React framework for web and native. Storybook showcased their latest Vitest-powered testing features. And so much more. We encourage you to watch all 43 talks. The speakers made a significant effort to share with us what each project has been up to.
Vite also got a refreshed landing page and a clean domain. You should update your URLs to point to the new vite.dev domain moving forward. The new design and implementation was done by VoidZero, by the same folks that made their website. Shoutout to Vicente Rodriguez and Simon Le Marchant.
The next Vite major is here
Vite 6 is the most significant major release since Vite 2. We're eager to partner with the ecosystem to keep expanding our shared commons through new APIs and, as usual, a more polished base upon which to build.
Quick links:
Docs
Translations: 简体中文, 日本語, Español, Português, 한국어, Deutsch
Migration Guide
GitHub Changelog
If you're new to Vite, we suggest reading the Getting Started and Features guides first.
We want to thank the more than 1K contributors to Vite Core and the maintainers and contributors of Vite plugins, integrations, tools, and translations that have helped us craft this new major. We invite you to get involved and help us improve Vite for the whole ecosystem. Learn more at our Contributing Guide.
To get started, we suggest helping triage issues, review PRs, send failing tests PRs based on open issues, and support others in Discussions and Vite Land's help forum. If you'd like to talk to us, join our Discord community and say hi on the #contributing channel.
For the latest news about the Vite ecosystem and Vite core, follow us on Bluesky, X, or Mastodon.
Getting started with Vite 6
You can use
pnpm create vite to quickly scaffold a Vite app with your preferred framework or play online with Vite 6 using vite.new. You can also run
pnpm create vite-extra to get access to templates from other frameworks and runtimes (Solid, Deno, SSR, and library starters).
create vite-extra templates are also available when you run
create vite under the
Others option.
The Vite starter templates are intended to be used as a playground to test Vite with different frameworks. When building your next project, you should reach out to the starter recommended by each framework.
create vite also provides a shortcut to setup proper starters by some frameworks, like
create-vue,
Nuxt 3,
SvelteKit,
Remix,
Analog, and
Angular.
Node.js Support
Vite 6 supports Node.js 18, 20, and 22+, similar to Vite 5. Node.js 21 support has been dropped. Vite drops Node.js support for older versions after their EOL. The Node.js 18 EOL is at the end of April 2025, after which we may release a new major to bump the required Node.js version.
Experimental Environment API
Vite is getting more flexible with the new Environment API. These new APIs will allow framework authors to offer a dev experience closer to production and for the Ecosystem to share new building blocks. Nothing changes if you're building a SPA; when you use Vite with a single client environment, everything works as before. And even for custom SSR apps, Vite 6 is backward compatible. The primary target audience for Environment API is framework authors.
For end users who are curious, Sapphi wrote a great Introduction to Environment API guide. It is a great place to start and understand why we're trying to make Vite even more flexible.
If you are a framework author or Vite plugin maintainer and would like to leverage the new APIs, you can learn more at the Environment API Guides.
We want to thank everyone involved in defining and implementing the new APIs. The story begins with Vite 2 adopting the unbundled SSR dev scheme pioneered by Rich Harris and the SvelteKit team. Vite's SSR transform then unlocked Anthony Fu and Pooya Parsa to create vite-node and improve Nuxt's Dev SSR story. Anthony went to use vite-node to power Vitest, and Vladimir Sheremet kept improving it as part of his work maintaining Vitest. At the beginning of 2023, Vladimir started working to upstream vite-node to Vite Core, and we released it as Runtime API in Vite 5.1 a year later. Feedback from ecosystem partners (special shout-out to the Cloudflare team) pushed us to do a more ambitious rework of Vite's environments. You can learn more about the story at Patak's ViteConf 24 talk.
Everyone on the Vite team participated in defining the new API, which was co-designed with feedback from many projects in the Ecosystem. Thanks to everyone involved! We encourage you to get involved if you're building a framework, plugin, or tool on top of Vite. The new APIs are experimental. We will work with the Ecosystem to review how the new APIs will be used and stabilize them for the next major. If you'd like to ask questions or give feedback, there is an open GitHub discussion here.
Main Changes
Default value for
resolve.conditions
JSON stringify
Extended support of asset references in HTML elements
postcss-load-config
Sass now uses modern API by default
Customize CSS output file name in library mode
And more changes that should only affect a few users
There is also a new Breaking Changes page that lists all planned, considering, and past changes in Vite.
Migrating to Vite 6
For most projects, the update to Vite 6 should be straightforward, but we advise reviewing the detailed Migration Guide before upgrading.
The complete list of changes is at the Vite 6 Changelog.
Acknowledgments
Vite 6 results from long work hours by our community of contributors, downstream maintainers, plugin authors, and the Vite Team. We appreciate the individuals and companies sponsoring Vite development. Vite is brought to you by VoidZero, in partnership with StackBlitz, Nuxt Labs, and Astro. A shout-out to sponsors on Vite's GitHub Sponsors and Vite's Open Collective.
Vite 7.0 is out!
June 24, 2025
We're happy to share the release of Vite 7! It has been 5 years since Evan You sent the first commit to the Vite repo, and nobody could have predicted how much the frontend ecosystem would change since then. Most modern frontend frameworks and tools are now working together, building on top of Vite's shared infrastructure. And they can innovate at a faster pace by sharing at a higher level. Vite is now being downloaded 31 million times a week, with a 14 million increase in the last seven months since the previous major release.
This year, we're making several big steps. To start with, ViteConf is going to be in person! The Vite Ecosystem will gather in Amsterdam on October 9-10! Organized by JSWorld in partnership with Bolt, VoidZero, and the Vite Core Team! We had three incredible ViteConf online editions, and we can't wait to meet in real life. Check out the speakers and get your ticket at the ViteConf site!
And VoidZero continues to make significant strides in its mission to build an open source unified development toolchain for the JavaScript ecosystem. Over the last year, the VoidZero team has been working on Rolldown, a Rust-based next-generation bundler, as part of a broader effort to modernize Vite's core. You can try out the Rolldown-powered Vite today by using the
rolldown-vite package instead of the default
vite package. It is a drop-in replacement, as Rolldown will become the default bundler for Vite in the future. Switching should reduce your build time, especially for larger projects. Read more at the Rolldown-vite announcement blog post and our migration guide.
Through a partnership between VoidZero and NuxtLabs, Anthony Fu is working on creating Vite DevTools. They will offer deeper and more insightful debugging and analysis for all Vite-based projects and frameworks. You can read more on the VoidZero and NuxtLabs join forces on Vite Devtools blog post.
Quick links:
Docs
New Translation: فارسی
Other Translations: 简体中文, 日本語, Español, Português, 한국어, Deutsch
Migration Guide
GitHub Changelog
Play online with Vite 7 using vite.new or scaffold a Vite app locally with your preferred framework running
pnpm create vite. Check out the Getting Started Guide for more information.
We invite you to help us improve Vite (joining the more than 1.1K contributors to Vite Core), our dependencies, or plugins and projects in the ecosystem. Learn more at our Contributing Guide. A good way to get started is by triaging issues, reviewing PRs, sending tests PRs based on open issues, and supporting others in Discussions or Vite Land's help forum. If you have questions, join our Discord community and talk to us in the #contributing channel.
Stay updated and connect with others building on top of Vite by following us on Bluesky, X, or Mastodon.
Node.js Support
Vite now requires Node.js 20.19+, 22.12+. We have dropped Node.js 18, now that it has reached its EOL at the end of April 2025.
We require these new ranges so Node.js supports
require(esm) without a flag. This allows us to distribute Vite 7.0 as ESM only without preventing the Vite JavaScript API from being required by CJS modules. Check out Anthony Fu's Move on to ESM-only for a detailed review of the current state of ESM in the ecosystem.
Default Browser Target Changed to Baseline Widely Available
Baseline gives us clear information about which web platform features work across their core browser set today. Baseline Widely Available indicates the feature is well-established and works across many devices and browser versions, being available across browsers for at least 30 months.
In Vite 7, the default browser target is changing from
'modules' to a new default:
'baseline-widely-available'. The set of browsers will be updated on each major to match the list of minimum browser versions compatible with Baseline Widely available features. The default browser value of
build.target is changing in Vite 7.0:
Chrome 87 → 107
Edge 88 → 107
Firefox 78 → 104
Safari 14.0 → 16.0
This change adds predictability to the default browser target for future releases.
Vitest
For Vitest users, Vite 7.0 is supported from Vitest 3.2. You can read more about how the Vitest team keeps improving Vite testing story in the Vitest 3.2 release blog post.
Environment API
Vite 6 was the most significant major release since Vite 2, adding new capabilities with the new experimental Environment API. We are keeping the new APIs as experimental while the ecosystem reviews how the new APIs fit on their projects and provide feedback. If you're building on top of Vite, we encourage you to test the new APIs and reach out to us in the open Feedback discussion here.
In Vite 7, we added a new
buildApp hook to let plugins coordinate the building of environments. Read more in the Environment API for Frameworks guide.
We want to thank the teams that have been testing the new APIs and helping us stabilize the new features. The Cloudflare team, for example, announced the 1.0 release of their Cloudflare Vite plugin, as well as official support for React Router v7. Their plugin shows the potential of Environment API for runtime providers. Learn more about their approach and future steps at "Just use Vite”… with the Workers runtime.
Migrating to Vite 7
Vite 7 should be a smooth update from Vite 6. We're removing already deprecated features, like Sass legacy API support and the
splitVendorChunkPlugin that shouldn't affect your projects. We still suggest you review the detailed Migration Guide before upgrading.
The complete list of changes is at the Vite 7 Changelog.
Acknowledgments
Vite 7 was crafted by the Vite Team with the help of the wide community of contributors, downstream maintainers, plugin authors. A special shout-out to sapphi-red for his remarkable work on
rolldown-vite and this release. Vite is brought to you by VoidZero, in partnership with Bolt and Nuxt Labs. We also want to thank our sponsors on Vite's GitHub Sponsors and Vite's Open Collective.
Vite 8.1 is out!
June 23, 2026
Vite 8 was released in March with a single unified bundler powered by Rolldown, opening the door to further improvements. It is now seeing 41.6 million weekly downloads, almost reaching the total downloads of Vite 7. Alongside resolving upgrade regressions, we've been working on new features, and we're excited to announce the release of Vite 8.1.
Quick links:
Docs
Translations: 简体中文, 日本語, Español, Português, 한국어, Deutsch, فارسی
GitHub Changelog
Play online with Vite 8.1 using vite.new or scaffold a Vite app locally with your preferred framework running
pnpm create vite. Check out the Getting Started Guide for more information.
We invite you to help us improve Vite (joining the more than 1.2K contributors to Vite Core), our dependencies, or plugins and projects in the ecosystem. Learn more at our Contributing Guide. A good way to get started is by triaging issues, reviewing PRs, sending tests PRs based on open issues, and supporting others in Discussions or Vite Land's help forum. If you have questions, join our Discord community and talk to us in the #contributing channel.
Stay updated and connect with others building on top of Vite by following us on Bluesky, X, or Mastodon.
Features
Experimental Bundled Dev Mode
Experimental support for bundled dev mode is now available. This was previously called as "Full Bundle Mode". This mode is to improve performance of huge applications that suffer from the number of modules.
In our initial testing with an app loading 10,000 React components, bundled dev mode achieved around 15x faster startup and 10x faster full page reloads compared to the unbundled dev server, while keeping HMR instant regardless of the application size. Early testing on real-world applications shows similar gains: the Linear team saw cold start rendering up to 3x faster, full reloads around 40% faster, and 10x fewer network requests.
::: details Why bundled dev mode?
Vite is known for its unbundled dev server approach, which is a main reason for Vite's speed and popularity when it was first introduced. This approach was initially an experiment to see just how far we could push the boundaries of development server performance without traditional bundling.
However, as projects scale in size and complexity, it has become clear that Vite's unbundled dev approach can degrade performance during development. Because each module is fetched separately, the browser must process a large number of requests, which increases startup and refresh overhead. This impact is especially noticeable in large applications and becomes more severe when developers are behind a network proxy, resulting in slower refresh times and a worse developer experience.
Bundled Dev Mode would allow serving bundled files not only in production but also during development, combining the best of both worlds:
Fast startup times even for large applications
Reduced network overhead on page refreshes
Maintained efficient HMR on top of ESM output
:::
Currently, it focuses on the browser side and the basic plugins and the main features. If you are using a third party plugin, it may not work with this mode. If you are using a minor feature, it may not work as well. We are working on expanding the support and preparing a document that clarifies the changes that may be needed on the plugin side. See the design document for more details about the roadmap.
To enable this mode, you can pass
--experimental-bundle or add
experimental.bundledDev: true to your
vite.config.js:
import { defineConfig } from 'vite'
export default defineConfig({
experimental: {
bundledDev: true,
},
})
Share your feedback in the discussion.
Experimental Chunk Import Map
In the output bundle, the import statement of a chunk includes the hash of that chunk. This is to ensure the new chunk is loaded if the chunk content has changed. However, this also causes the hash of the chunk importing the changed chunk to change, cascading the change to all the chunks that import the changed chunk transitively.
digraph chunk_hash_cascade {
rankdir=TB
node [shape=box style="rounded,filled" fontname="Arial" fontsize=11 margin="0.25,0.12" fontcolor="${#3c3c43|#ffffff}" color="${#c2c2c4|#3c3f44}"]
edge [color="${#67676c|#98989f}" fontname="Arial" fontsize=10 fontcolor="${#67676c|#98989f}"]
bgcolor="transparent"
utils [label="utils.[e5f6 → 88xx].js\ncontent edited" fillcolor="${#fcf4dc|#38301a}" color="${#e0a800|#d4a72c}"]
page [label="page.[c3d4 → 77yy].js\nre-hashed by cascade" fillcolor="${#fde8e8|#3a1f22}" color="${#d5393e|#f66f81}"]
entry [label="entry.[a1b2 → 99zz].js\nre-hashed by cascade" fillcolor="${#fde8e8|#3a1f22}" color="${#d5393e|#f66f81}"]
entry -> page [label=" imports (embeds hash)\l" color="${#d5393e|#f66f81}" fontcolor="${#d5393e|#f66f81}"]
page -> utils [label=" imports (embeds hash)\l" color="${#d5393e|#f66f81}" fontcolor="${#d5393e|#f66f81}"]
}
The experimental chunk import map feature solves this problem utilizing import maps and improves the cache efficiency. This feature is built on top of Rolldown's feature, but adds the support for Vite specific features. Huge thanks to Taisei Mima for their research and initial implementation of this feature!
Note that
experimental.renderBuiltUrl currently does not work with this option.
See the guide and the option docs for more details. Share your feedback in the discussion.
Wasm ESM integration Support
Wasm ESM integration proposal is now supported in Vite. You can now import wasm files and use the exported functions directly:
import { add } from './add.wasm'
console.log(add(1, 2)) // 3
Huge thanks to Menci for their creation and maintenance of vite-plugin-wasm while the proposal was early stages and also for upstreaming the implementation to Vite core!
See the guide for more details.
One step closer to use Lightning CSS by default
We have worked with the Lightning CSS team to add features that was supported by PostCSS but was lacking in Lightning CSS. Vite 8.1 now has these two features:
Allow external CSS files imported in CSS files (lightningcss#479)
Register file dependencies by plugins (lightningcss#877)
We are thinking of changing the default CSS preprocessor to Lightning CSS in the next major release. Please try it out by
css.transformer: 'lightningcss' and share your feedback in the discussion.
Case Insensitive Matching For
import.meta.glob
import.meta.glob now supports
caseSensitive option to match files case insensitively.
// matches ./dir/Module1.js
const modules = import.meta.glob('./dir/module*.js', {
caseSensitive: false,
})
Asset Discovery For Custom HTML Elements And Attributes
Previously, Vite would only discover assets for the elements and attributes that was pre-defined. Now, you can use the
html.additionalAssetSources option to add more elements and attributes.
import { defineConfig } from 'vite'
export default defineConfig({
html: {
additionalAssetSources: {
'html-import': {
srcAttributes: ['src'],
},
img: {
srcAttributes: ['data-src-dark', 'data-src-light'],
},
},
},
})
Other Changes
Check out the Changelog for other features and bug fixes.
Acknowledgments
Vite 8.1 is possible thanks to our community of contributors, maintainers in the ecosystem, and the Vite Team. Vite is brought to you by VoidZero, in partnership with Bolt and Nuxt Labs. We also want to thank our sponsors on Vite's GitHub Sponsors and Vite's Open Collective.
Vite 8 Beta: The Rolldown-powered Vite
December 3, 2025
TL;DR: The first beta of Vite 8, powered by Rolldown, is now available. Vite 8 ships significantly faster production builds and unlocks future improvement possibilities. You can try the new release by upgrading
vite to version
8.0.0-beta.0 and reading the migration guide.
We're excited to release the first beta of Vite 8. This release unifies the underlying toolchain and brings better consistent behaviors, alongside significant build performance improvements. Vite now uses Rolldown as its bundler, replacing the previous combination of esbuild and Rollup.
A new bundler for the web
Vite previously relied on two bundlers to meet differing requirements for development and production builds:
esbuild for fast compilation during development
Rollup for bundling, chunking, and optimizing production builds
This approach lets Vite focus on developer experience and orchestration instead of reinventing parsing and bundling. However, maintaining two separate bundling pipelines introduced inconsistencies: separate transformation pipelines, different plugin systems and a growing amount of glue code to keep bundling behavior aligned between development and production.
To solve this, VoidZero team has built Rolldown, the next-generation bundler with the goal to be used in Vite. It is designed for:
Performance: Rolldown is written in Rust and operates at native speed. It matches esbuild’s performance level and is 10–30× faster than Rollup.
Compatibility: Rolldown supports the same plugin API as Rollup and Vite. Most Vite plugins work out of the box with Vite 8.
More Features: Rolldown unlocks more advanced features for Vite, including full bundle mode, more flexible chunk split control, module-level persistent cache, Module Federation, and more.
Unifying the toolchain
The impact of Vite’s bundler swap goes beyond performance. Bundlers leverage parsers, resolvers, transformers, and minifiers. Rolldown uses Oxc, another project led by VoidZero, for these purposes.
That makes Vite the entry point to an end-to-end toolchain maintained by the same team: The build tool (Vite), the bundler (Rolldown) and the compiler (Oxc).
This alignment ensures behavior consistency across the stack, and allows us to rapidly adopt and align with new language specifications as JavaScript continues to evolve. It also unlocks a wide range of improvements that previously couldn’t be done by Vite alone. For example, we can leverage Oxc’s semantic analysis to perform better tree-shaking in Rolldown.
How Vite migrated to Rolldown
The migration to a Rolldown-powered Vite is a foundational change. Therefore, our team took deliberate steps to implement it without sacrificing stability or ecosystem compatibility.
First, a separate
rolldown-vite package was released as a technical preview. This allowed us to work with early adopters without affecting the stable version of Vite. Early adopters benefited from Rolldown’s performance gains while providing valuable feedback. Highlights:
Linear's production build times were reduced from 46s to 6s
Ramp reduced their build time by 57%
Mercedes-Benz.io cut their build time down by up to 38%
Beehiiv reduced their build time by 64%
Next, we set up a test suite for validating key Vite plugins against
rolldown-vite. This CI job helped us catch regressions and compatibility issues early, especially for frameworks and meta-frameworks such as SvelteKit, react-router and Storybook.
Lastly, we built a compatibility layer to help migrate developers from Rollup and esbuild options to the corresponding Rolldown options.
As a result, there is a smooth migration path to Vite 8 for everyone.
Migrating to Vite 8 Beta
Since Vite 8 touches the core build behavior, we focused on keeping the configuration API and plugin hooks unchanged. We created a migration guide to help you upgrade.
There are two available upgrade paths:
Direct Upgrade: Update
vite in
package.json and run the usual dev and build commands.
Gradual Migration: Migrate from Vite 7 to the
rolldown-vite package, and then to Vite 8. This allows you to identify incompatibilities or issues isolated to Rolldown without other changes to Vite. (Recommended for larger or complex projects)
[!IMPORTANT]
If you are relying on specific Rollup or esbuild options, you might need to make some adjustments to your Vite config. Please refer to the migration guide for detailed instructions and examples.
As with all non-stable, major releases, thorough testing is recommended after upgrading to ensure everything works as expected. Please make sure to report any issues.
If you use a framework or tool that uses Vite as dependency, for example Astro, Nuxt, or Vitest, you have to override the
vite dependency in your
package.json, which works slightly different depending on your package manager:
:::code-group
{
"overrides": {
"vite": "8.0.0-beta.0"
}
}
{
"resolutions": {
"vite": "8.0.0-beta.0"
}
}
{
"pnpm": {
"overrides": {
"vite": "8.0.0-beta.0"
}
}
}
{
"overrides": {
"vite": "8.0.0-beta.0"
}
}
:::
After adding these overrides, reinstall your dependencies and start your development server or build your project as usual.
Additional Features in Vite 8
In addition to shipping with Rolldown, Vite 8 comes with:
Built-in tsconfig
paths support: Developers can enable it by setting
resolve.tsconfigPaths to
true. This feature has a small performance cost and is not enabled by default.
emitDecoratorMetadata support: Vite 8 now has built-in automatic support for TypeScript's
emitDecoratorMetadata option. See the Features page for more details.
Looking Ahead
Speed has always been a defining feature for Vite. The integration with Rolldown and, by extension, Oxc means JavaScript developers benefit from Rust’s speed. Upgrading to Vite 8 should result in performance gains simply from using Rust.
We are also excited to ship Vite’s Full Bundle Mode soon, which drastically improves Vite’s dev server speed for large projects. Preliminary results show 3× faster dev server startup, 40% faster full reloads, and 10× fewer network requests.
Another defining Vite feature is the plugin ecosystem. We want JavaScript developers to continue extending and customizing Vite in JavaScript, the language they’re familiar with, while benefiting from Rust’s performance gains. Our team is collaborating with VoidZero team to accelerate JavaScript plugin usage in these Rust-based systems.
Upcoming optimizations that are currently experimental:
Raw AST transfer. Allow JavaScript plugins to access the Rust-produced AST with minimal overhead.
Native MagicString transforms. Simple custom transforms with logic in JavaScript but computation in Rust.
Connect with us
If you've tried Vite 8 beta, then we'd love to hear your feedback! Please report any issues or share your experience:
Discord: Join our community server for real-time discussions
GitHub: Share feedback on GitHub discussions
Issues: Report issues on the rolldown-vite repository for bugs and regressions
Wins: Share your improved build times in the rolldown-vite-perf-wins repository
We appreciate all reports and reproduction cases. They help guide us towards the release of a stable 8.0.0.
Vite 8.0 is out!
March 12, 2026
We're thrilled to announce the stable release of Vite 8! When Vite first launched, we made a pragmatic bet on two bundlers: esbuild for speed during development, and Rollup for optimized production builds. That bet served us well for years. We're very grateful to the Rollup and esbuild maintainers. Vite wouldn't have succeeded without them. Today, it resolves into one: Vite 8 ships with Rolldown as its single, unified, Rust-based bundler, delivering up to 10-30x faster builds while maintaining full plugin compatibility. This is the most significant architectural change since Vite 2.
Vite is now being downloaded 65 million times a week, and the ecosystem continues to grow with every release. To help developers navigate the ever-expanding plugin landscape, we also launched registry.vite.dev, a searchable directory of plugins for Vite, Rolldown, and Rollup that collects plugin data from npm daily.
Quick links:
Docs
Translations: 简体中文, 日本語, Español, Português, 한국어, Deutsch, فارسی
Migration Guide
GitHub Changelog
Play online with Vite 8 using vite.new or scaffold a Vite app locally with your preferred framework running
pnpm create vite. Check out the Getting Started Guide for more information.
We invite you to help us improve Vite (joining the more than 1.2K contributors to Vite Core), our dependencies, or plugins and projects in the ecosystem. Learn more at our Contributing Guide. A good way to get started is by triaging issues, reviewing PRs, sending tests PRs based on open issues, and supporting others in Discussions or Vite Land's help forum. If you have questions, join our Discord community and talk to us in the #contributing channel.
Stay updated and connect with others building on top of Vite by following us on Bluesky, X, or Mastodon.
The Rolldown-Powered Vite
The problem
Since its earliest versions, Vite relied on two separate bundlers to serve different needs. esbuild handled fast compilation during development (dependency pre-bundling and TypeScript/JSX transforms) that made the dev experience feel instant. Rollup handled production bundling, chunking, and optimization, with its rich plugin API powering the entire Vite plugin ecosystem.
This dual-bundler approach served Vite well for years. It allowed us to focus on developer experience and orchestration rather than reinventing parsing and bundling from scratch. But it came with trade-offs. Two separate transformation pipelines meant two separate plugin systems, and an increasing amount of glue code needed to keep the two pipelines in sync. Edge cases around inconsistent module handling accumulated over time, and every alignment fix in one pipeline risked introducing differences in the other.
The solution
Rolldown is a Rust-based bundler built by the VoidZero team to address these challenges head-on. It was designed with three goals:
Performance: Written in Rust, Rolldown operates at native speed. In benchmarks, it is 10-30x faster than Rollup matching esbuild's performance level.
Compatibility: Rolldown supports the same plugin API as Rollup and Vite. Most existing Vite plugins work out of the box with Vite 8.
Advanced features: A single unified bundler unlocks capabilities that were difficult or impossible with the dual-bundler setup, including full bundle mode, more flexible chunk splitting, module-level persistent caching, and Module Federation support.
The journey to stable
The migration to Rolldown was deliberate and community-driven. First, a separate
rolldown-vite package was released as a technical preview, allowing early adopters to test Rolldown's integration without affecting the stable version of Vite. The feedback from those early adopters was invaluable. They pushed the integration through real-world codebases of every shape and size, surfacing edge cases and compatibility issues we could address before a wider release. We also set up a dedicated CI suite validating key Vite plugins and frameworks against the new bundler, catching regressions early and building confidence in the migration path.
In December 2025, we shipped the Vite 8 beta with Rolldown fully integrated. During the beta period, Rolldown itself progressed from beta to a release candidate, with continuous improvements driven by the testing and feedback of the Vite community.
Real-world performance
During the preview and beta phases of
rolldown-vite, several companies reported measurable reductions in production build times:
Linear: Production build times dropped from 46s to 6s
Ramp: 57% build time reduction
Mercedes-Benz.io: Up to 38% build time reduction
Beehiiv: 64% build time reduction
For large projects, the impact can be especially noticeable, and we expect further improvements as Rolldown continues to evolve.
A unified toolchain
With Vite 8, Vite becomes the entry point to an end-to-end toolchain with closely collaborating teams: the build tool (Vite), the bundler (Rolldown), and the compiler (Oxc). This alignment ensures consistent behavior across the entire stack, from parsing and resolving to transforming and minifying. It also means we can rapidly adopt new language specifications as JavaScript evolves. And by integrating deeply across layers, we can pursue optimizations that were previously out of reach, such as leveraging Oxc's semantic analysis for better tree-shaking in Rolldown.
Thank you to the community
None of this would have been possible without the broader community. We want to extend our deep thanks to the framework teams (SvelteKit, React Router, Storybook, Astro, Nuxt, and many others) who tested
rolldown-vite early, filed detailed bug reports, and worked with us to resolve compatibility issues. We are equally grateful to every developer who tried the beta, shared their build time improvements, and reported the rough edges that helped us polish this release. Your willingness to test the migration on real projects helped make the transition to Rolldown smoother and more reliable.
Node.js Support
Vite 8 requires Node.js 20.19+, 22.12+, the same requirements as Vite 7. These ranges ensure Node.js supports
require(esm) without a flag, allowing Vite to be distributed as ESM only.
Additional Features
Beyond the Rolldown integration, Vite 8 includes several notable features:
Integrated Devtools: Vite 8 ships
devtools option to enable Vite Devtools, a developer tooling for debugging and analysis. Vite Devtools provide deeper insights into your Vite-powered projects directly from the dev server.
Built-in tsconfig
paths support: Developers can enable TypeScript path alias resolution by setting
resolve.tsconfigPaths to
true. This has a small performance cost and is not enabled by default.
emitDecoratorMetadata support: Vite 8 now has built-in automatic support for TypeScript's
emitDecoratorMetadata option, removing the need for external plugins. See the Features page for details.
Wasm SSR support:
.wasm?init imports now work in SSR environments, expanding Vite's WebAssembly feature to server-side rendering.
Browser console forwarding: Vite 8 can forward browser console logs and errors to the dev server terminal. This is especially useful when working with coding agents, as runtime client errors become visible in the CLI output. Enable it with
server.forwardConsole, which activates automatically when a coding agent is detected.
@vitejs/plugin-react v6
Alongside Vite 8, we are releasing
@vitejs/plugin-react v6. The plugin uses Oxc for React Refresh transform. Babel is no longer a dependency and the installation size is smaller.
For projects that need the React Compiler, v6 provides a
reactCompilerPreset helper that works with
@rolldown/plugin-babel, giving you an explicit opt-in path without burdening the default setup.
See the Release Notes for more details.
Note that v5 still works with Vite 8, so you can upgrade the plugin after upgrading Vite.
Looking Ahead
The Rolldown integration opens the door to improvements and optimizations. Here is what we are working on next:
Full Bundle Mode (experimental): This mode bundles modules during development, similar to production builds. Preliminary results show 3x faster dev server startup, 40% faster full reloads, and 10x fewer network requests. This is especially impactful for large projects where the unbundled dev approach hits scaling limits.
Raw AST transfer: Allows JavaScript plugins to access the Rust-produced AST with minimal serialization overhead, bridging the performance gap between Rust internals and JS plugin code.
Native MagicString transforms: Enables custom transforms where the logic lives in JavaScript but the string manipulation computation runs in Rust.
Stabilizing the Environment API: We are working to make the Environment API stable. The ecosystem has started regular meetings to better collaborate together.
Install Size
We want to be transparent about changes to Vite's install size. Vite 8 is approximately 15 MB larger than Vite 7 on its own. This comes from two main sources:
~10 MB from lightningcss: Previously an optional peer dependency, lightningcss is now a normal dependency to provide better CSS minification out of the box.
~5 MB from Rolldown: The Rolldown binary is larger than esbuild + Rollup mainly due to performance optimizations that favor speed over binary size.
We will continue monitoring and working to reduce install size as Rolldown matures.
Migrating to Vite 8
For most projects, upgrading to Vite 8 should be a smooth process. We built a compatibility layer that auto-converts existing
esbuild and
rollupOptions configuration to their Rolldown and Oxc equivalents, so many projects will work without any config changes.
For larger or more complex projects, we recommend the gradual migration path: first switch from
vite to the
rolldown-vite package on Vite 7 to isolate any Rolldown-specific issues, then upgrade to Vite 8. This two-step approach makes it easy to identify whether any issues come from the bundler change or from other Vite 8 changes.
Please review the detailed Migration Guide before upgrading. The complete list of changes is in the Vite 8 Changelog.
Thank You, Rollup and esbuild
As Vite moves to Rolldown, we want to take a moment to express our deep gratitude to the two projects that made Vite possible.
Rollup has been Vite's production bundler since the very beginning. Its elegant plugin API design proved so well-conceived that Rolldown adopted it as its own, and Vite's entire plugin ecosystem exists because of the foundation Rollup laid. The quality and thoughtfulness of Rollup's architecture shaped how Vite thinks about extensibility. Thank you, Rich Harris for creating Rollup, and Lukas Taegert-Atkinson and the Rollup team for maintaining and evolving it into something that has had such a lasting impact on the web tooling ecosystem.
esbuild powered Vite's remarkably fast development experience from its early days: dependency pre-bundling, TypeScript and JSX transforms that completed in milliseconds rather than hundreds. esbuild proved that build tools could be orders of magnitude faster, and its speed set the bar that inspired an entire generation of Rust and Go-based tooling. Thank you, Evan Wallace, for showing all of us what was possible.
Without these two projects, Vite would not exist as it does today. Even as we move forward with Rolldown, the influence of Rollup and esbuild is deeply embedded in Vite's DNA, and we are grateful for everything they have given to the ecosystem. You can learn more about all the projects and people Vite depends on at our Acknowledgements page.
Acknowledgments
Vite 8 was led by sapphi-red and the Vite Team with the help of the wide community of contributors, downstream maintainers, and plugin authors. We want to thank the Rolldown team for their close collaboration in making the Rolldown-powered Vite 8 possible. We are also especially grateful to everyone who participated in the
rolldown-vite preview and the Vite 8 beta period. Your testing, bug reports, and feedback made the Rolldown migration possible and shaped this release into something we are proud of.
Vite is brought to you by VoidZero, in partnership with Bolt and NuxtLabs. We also want to thank our sponsors on Vite's GitHub Sponsors and Vite's Open Collective.
Cloudflare supports Vite's mission
June 4, 2026
Today marks the start of a new stage for Vite. VoidZero is joining Cloudflare. You can read the full story from Evan You in VoidZero's announcement. In Cloudflare's blog post, they explain why they are investing in the Vite stack, which has now become part of the web's foundational infrastructure. Vite's team governance, mission, and philosophy aren't changing:
Vite remains open source under the MIT license.
Vite remains vendor-agnostic, applications built with vite are meant to run anywhere.
Vite continues to be stewarded by the Vite team, which includes members employed by different organizations and independent members.
Vite's Open Collective funds are managed by the Vite team and are used to fund independent core team members, dependencies, and other key projects in the ecosystem.
The Vite team members employed by VoidZero are all joining Cloudflare and will continue to work on Vite.
As stated in the VoidZero and Cloudflare announcements, the same applies to Vitest, Rolldown, Oxc, and Vite+.
Cloudflare's Vite Ecosystem Open Source Fund
Cloudflare is committed to helping Vite remain neutral and has also announced a new $1M open source fund for the Vite ecosystem. Alongside Vite's Open Collective (which stays managed by the Vite team), these funds will allow us to further improve Vite and its ecosystem, including:
Fund more popular plugins and toolings in the ecosystem.
Adopt a core team member stipend to support independent team members.
Work closely with teams of the Vite stack, including Rolldown, Oxc, and Vite+.
Work closely with the ecosystem maintainers from frameworks, plugins, and deployment platforms.
Work with standard bodies and adopt new web platform features faster.
Audit and release security issues more quickly.
Many of which we had already started working on, which will help accelerate the process.
Thank You
We want to thank our current sponsors through GitHub Sponsors and Open Collective, which remain invaluable to us. We'd also like to thank the teams from projects, ecosystem frameworks, and plugins whose collaboration helped Vite reach where it is today. And also to the 1250+ contributors to the Vite repo and the users who keep providing valuable feedback to improve Vite.
We talked about what's next in Vite 8's announcement. We have made good progress towards Full Bundle Mode and the new Ecosystem Sync Calls, that gathers members of different frameworks, deploy platforms, and plugins, have become a great motor for new ideas to further expand Vite's capabilities. We think we're on a good trajectory to stabilize Vite's Environment API on Vite 9. As Vite's story continues to unfold, we look forward to the long path ahead to keep building the web together.
Changes
HMR `hotUpdate` Plugin Hook
::: tip Feedback
Give us feedback at Environment API feedback discussion
:::
We're planning to deprecate the
handleHotUpdate plugin hook in favor of
hotUpdate hook to be Environment API aware, and handle additional watch events with
create and
delete.
Affected scope:
Vite Plugin Authors
::: warning Future Deprecation
hotUpdate was first introduced in
v6.0. The deprecation of
handleHotUpdate is planned for a future major. We don't recommend moving away from
handleHotUpdate yet. If you want to experiment and give us feedback, you can use the
future.removePluginHookHandleHotUpdate to
"warn" in your vite config.
:::
Motivation
The
handleHotUpdate hook allows to perform custom HMR update handling. A list of modules to be updated is passed in the
HmrContext.
interface HmrContext {
file: string
timestamp: number
modules: Array
read: () => string | Promise
server: ViteDevServer
}
This hook is called once for all environments, and the passed modules have mixed information from the Client and SSR environments only. Once frameworks move to custom environments, a new hook that is called for each of them is needed.
The new
hotUpdate hook works in the same way as
handleHotUpdate but it is called for each environment and receives a new
HotUpdateOptions instance:
interface HotUpdateOptions {
type: 'create' | 'update' | 'delete'
file: string
timestamp: number
modules: Array
read: () => string | Promise
server: ViteDevServer
}
The current dev environment can be accessed like in other Plugin hooks with
this.environment. The
modules list will now be module nodes from the current environment only. Each environment update can define different update strategies.
This hook is also now called for additional watch events and not only for
'update'. Use
type to differentiate between them.
Migration Guide
Filter and narrow down the affected module list so that the HMR is more accurate.
handleHotUpdate({ modules }) {
return modules.filter(condition)
}
// Migrate to:
hotUpdate({ modules }) {
return modules.filter(condition)
}
Return an empty array and perform a full reload:
handleHotUpdate({ server, modules, timestamp }) {
// Invalidate modules manually
const invalidatedModules = new Set()
for (const mod of modules) {
server.moduleGraph.invalidateModule(
mod,
invalidatedModules,
timestamp,
true
)
}
server.ws.send({ type: 'full-reload' })
return []
}
// Migrate to:
hotUpdate({ modules, timestamp }) {
// Invalidate modules manually
const invalidatedModules = new Set()
for (const mod of modules) {
this.environment.moduleGraph.invalidateModule(
mod,
invalidatedModules,
timestamp,
true
)
}
this.environment.hot.send({ type: 'full-reload' })
return []
}
Return an empty array and perform complete custom HMR handling by sending custom events to the client:
handleHotUpdate({ server }) {
server.ws.send({
type: 'custom',
event: 'special-update',
data: {}
})
return []
}
// Migrate to...
hotUpdate() {
this.environment.hot.send({
type: 'custom',
event: 'special-update',
data: {}
})
return []
}
Breaking Changes
List of breaking changes in Vite including API deprecations, removals, and changes. Most of the changes below can be opt-in using the
future option in your Vite config.
Planned
These changes are planned for the next major version of Vite. The deprecation or usage warnings will guide you where possible, and we're reaching out to framework, plugin authors, and users to apply these changes.
this.environment in Hooks
HMR
hotUpdate Plugin Hook
SSR Using
ModuleRunner API
Considering
These changes are being considered and are often experimental APIs that intend to improve upon current usage patterns. As not all changes are listed here, please check out the Experimental Label in Vite GitHub Discussions for the full list.
We don't recommend switching to these APIs yet. They are included in Vite to help us gather feedback. Please check these proposals and let us know how they work in your use case in each's linked GitHub Discussions.
Move to Per-environment APIs
Shared Plugins During Build
Past
The changes below have been done or reverted. They are no longer relevant in the current major version.
No past changes yet
Move to Per-environment APIs
::: tip Feedback
Give us feedback at Environment API feedback discussion
:::
Multiple APIs from
ViteDevServer related to module graph and modules transforms have been moved to the
DevEnvironment instances.
Affected scope:
Vite Plugin Authors
::: warning Future Deprecation
The
Environment instance was first introduced at
v6.0. The deprecation of
server.moduleGraph and other methods that are now in environments is planned for a future major. We don't recommend moving away from server methods yet. To identify your usage, set these in your vite config.
future: {
removeServerModuleGraph: 'warn',
removeServerReloadModule: 'warn',
removeServerPluginContainer: 'warn',
removeServerHot: 'warn',
removeServerTransformRequest: 'warn',
removeServerWarmupRequest: 'warn',
}
:::
Motivation
In Vite v5 and before, a single Vite dev server always had two environments (
client and
ssr). The
server.moduleGraph had mixed modules from both of these environments. Nodes were connected through
clientImportedModules and
ssrImportedModules lists (but a single
importers list was maintained for each). A transformed module was represented by an
id and a
ssr boolean. This boolean needed to be passed to APIs, for example
server.moduleGraph.getModuleByUrl(url, ssr) and
server.transformRequest(url, { ssr }).
In Vite v6, it is now possible to create any number of custom environments (
client,
ssr,
edge, etc). A single
ssr boolean isn't enough anymore. Instead of changing the APIs to be of the form
server.transformRequest(url, { environment }), we moved these methods to the environment instance allowing them to be called without a Vite dev server.
Migration Guide
server.moduleGraph ->
environment.moduleGraph
server.reloadModule(module) ->
environment.reloadModule(module)
server.pluginContainer ->
environment.pluginContainer
server.transformRequest(url, ssr) ->
environment.transformRequest(url)
server.warmupRequest(url, ssr) ->
environment.warmupRequest(url)
server.hot ->
server.client.environment.hot
Shared Plugins during Build
::: tip Feedback
Give us feedback at Environment API feedback discussion
:::
See Shared plugins during build.
Affected scope:
Vite Plugin Authors
::: warning Future Default Change
builder.sharedConfigBuild was first introduced in
v6.0. You can set it true to check how your plugins work with a shared config. We're looking for feedback about changing the default in a future major once the plugin ecosystem is ready.
:::
Motivation
Align dev and build plugin pipelines.
Migration Guide
To be able to share plugins across environments, plugin state must be keyed by the current environment. A plugin of the following form will count the number of transformed modules across all environments.
function CountTransformedModulesPlugin() {
let transformedModules
return {
name: 'count-transformed-modules',
buildStart() {
transformedModules = 0
},
transform(id) {
transformedModules++
},
buildEnd() {
console.log(transformedModules)
},
}
}
If we instead want to count the number of transformed modules for each environment, we need to keep a map:
function PerEnvironmentCountTransformedModulesPlugin() {
const state = new Map()
return {
name: 'count-transformed-modules',
perEnvironmentStartEndDuringDev: true,
buildStart() {
state.set(this.environment, { count: 0 })
},
transform(id) {
state.get(this.environment).count++
},
buildEnd() {
console.log(this.environment.name, state.get(this.environment).count)
},
}
}
To simplify this pattern, Vite exports a
perEnvironmentState helper:
function PerEnvironmentCountTransformedModulesPlugin() {
const state = perEnvironmentState<{ count: number }>(() => ({ count: 0 }))
return {
name: 'count-transformed-modules',
perEnvironmentStartEndDuringDev: true,
buildStart() {
state(this).count = 0
},
transform(id) {
state(this).count++
},
buildEnd() {
console.log(this.environment.name, state(this).count)
},
}
}
SSR Using `ModuleRunner` API
::: tip Feedback
Give us feedback at Environment API feedback discussion
:::
server.ssrLoadModule has been replaced by importing from a Module Runner.
Affected scope:
Vite Plugin Authors
::: warning Future Deprecation
ModuleRunner was first introduced in
v6.0. The deprecation of
server.ssrLoadModule is planned for a future major. To identify your usage, set
future.removeSsrLoadModule to
"warn" in your vite config.
:::
Motivation
The
server.ssrLoadModule(url) only allows importing modules in the
ssr environment and can only execute the modules in the same process as the Vite dev server. For apps with custom environments, each is associated with a
ModuleRunner that may be running in a separate thread or process. To import modules, we now have
moduleRunner.import(url).
Migration Guide
Check out the Environment API for Frameworks Guide.
server.ssrFixStacktrace and
server.ssrRewriteStacktrace do not have to be called when using the Module Runner APIs. The stack traces will be updated unless
sourcemapInterceptor is set to
false.
`this.environment` in Hooks
::: tip Feedback
Give us feedback at Environment API feedback discussion
:::
Before Vite 6, only two environments were available:
client and
ssr. A single
options.ssr plugin hook argument in
resolveId,
load and
transform allowed plugin authors to differentiate between these two environments when processing modules in plugin hooks. In Vite 6, a Vite application can define any number of named environments as needed. We're introducing
this.environment in the plugin context to interact with the environment of the current module in hooks.
Affected scope:
Vite Plugin Authors
::: warning Future Deprecation
this.environment was introduced in
v6.0. The deprecation of
options.ssr is planned for a future major. At that point we'll start recommending migrating your plugins to use the new API. To identify your usage, set
future.removePluginHookSsrArgument to
"warn" in your vite config.
:::
Motivation
this.environment not only allow the plugin hook implementation to know the current environment name, it also gives access to the environment config options, module graph information, and transform pipeline (
environment.config,
environment.moduleGraph,
environment.transformRequest()). Having the environment instance available in the context allows plugin authors to avoid the dependency of the whole dev server (typically cached at startup through the
configureServer hook).
Migration Guide
For the existing plugin to do a quick migration, replace the
options.ssr argument with
this.environment.config.consumer === 'server' in the
resolveId,
load and
transform hooks:
import { Plugin } from 'vite'
export function myPlugin(): Plugin {
return {
name: 'my-plugin',
resolveId(id, importer, options) {
const isSSR = options.ssr // [!code --]
const isSSR = this.environment.config.consumer === 'server' // [!code ++]
if (isSSR) {
// SSR specific logic
} else {
// Client specific logic
}
},
}
}
For a more robust long term implementation, the plugin hook should handle for multiple environments using fine-grained environment options instead of relying on the environment name.
Acknowledgements
Acknowledgements
Vite is built upon the shoulders of giants. We would like to express our gratitude to all the projects, contributors, and sponsors that make Vite possible.
Contributors
Vite is developed by an international team of contributors. See the Team page to meet the core team members.
We also thank all the contributors on GitHub who have helped improve Vite through code contributions, bug reports, documentation, and documentation translation.
Sponsors
Vite's development is supported by generous sponsors. You can support Vite through GitHub Sponsors or Open Collective.
Dependencies
Vite depends on these amazing open source projects:
Notable Dependencies
{{ dep.name }}
Repo
Sponsor
by {{ dep.author }}
{{ dep.description }}
Bundled Dependency Authors
Author
Packages
{{ author.name }}
Sponsor
::: tip For package authors
This section is automatically generated from the
author and
funding fields in each package's
package.json. If you'd like to update how your package appears here, you can update these fields in your package.
:::
Development Tools
Vite's development workflow is powered by these tools:
{{ dep.name }}
Repo
Sponsor
by {{ dep.author }}
{{ dep.description }}
Past Notable Dependencies
We also thank the maintainers of these projects that Vite used in previous versions:
Package
Description
Links
{{ dep.name }}
{{ dep.description }}
Repo
Config
Build Options
Unless noted, the options in this section are only applied to build.
build.target
Type:
string | string[]
Default:
'baseline-widely-available'
Related: Browser Compatibility
Browser compatibility target for the final bundle. The default value is a Vite special value,
'baseline-widely-available', which targets the minimum browser versions compatible with Baseline Widely Available as of a date fixed for each major release (2026-01-01 for this major). Specifically, it is
['chrome111', 'edge111', 'firefox114', 'safari16.4', 'ios16.4'].
Another special value is
'esnext' - which assumes native dynamic imports support and will only perform minimal transpiling.
The transform is performed with Oxc Transformer and the value should be a valid Oxc Transformer target option. Custom targets can either be an ES version (e.g.
es2015), a browser with version (e.g.
chrome58), or an array of multiple target strings.
Note the build will output a warning if the code contains features that cannot be safely transpiled by Oxc. See Oxc docs for more details.
build.modulePreload
Type:
boolean | { polyfill?: boolean, resolveDependencies?: ResolveModulePreloadDependenciesFn }
Default:
{ polyfill: true }
By default, a module preload polyfill is automatically injected. The polyfill is auto injected into the proxy module of each
index.html entry. If the build is configured to use a non-HTML custom entry via
build.rolldownOptions.input, then it is necessary to manually import the polyfill in your custom entry:
import 'vite/modulepreload-polyfill'
Note: the polyfill does not apply to Library Mode. If you need to support browsers without native dynamic import, you should probably avoid using it in your library.
The polyfill can be disabled using
{ polyfill: false }.
The list of chunks to preload for each dynamic import is computed by Vite. By default, an absolute path including the
base will be used when loading these dependencies. If the
base is relative (
'' or
'./'),
import.meta.url is used at runtime to avoid absolute paths that depend on the final deployed base.
There is experimental support for fine grained control over the dependencies list and their paths using the
resolveDependencies function. Give Feedback. It expects a function of type
ResolveModulePreloadDependenciesFn:
type ResolveModulePreloadDependenciesFn = (
url: string,
deps: string[],
context: {
hostId: string
hostType: 'html' | 'js'
},
) => string[]
The
resolveDependencies function will be called for each dynamic import with a list of the chunks it depends on, and it will also be called for each chunk imported in entry HTML files. A new dependencies array can be returned with these filtered or more dependencies injected, and their paths modified. The
deps paths are relative to the
build.outDir. The return value should be a relative path to the
build.outDir.
/** @type {import('vite').UserConfig} */
const config = {
// prettier-ignore
build: {
// ---cut-before---
modulePreload: {
resolveDependencies: (filename, deps, { hostId, hostType }) => {
return deps.filter(condition)
},
},
// ---cut-after---
},
}
The resolved dependency paths can be further modified using
experimental.renderBuiltUrl.
build.polyfillModulePreload
Type:
boolean
Default:
true
Deprecated use
build.modulePreload.polyfill instead
Whether to automatically inject a module preload polyfill.
build.outDir
Type:
string
Default:
dist
Specify the output directory (relative to project root).
build.assetsDir
Type:
string
Default:
assets
Specify the directory to nest generated assets under (relative to
build.outDir). This is not used in Library Mode.
build.assetsInlineLimit
Type:
number |
((filePath: string, content: Buffer) => boolean | undefined)
Default:
4096 (4 KiB)
Imported or referenced assets that are smaller than this threshold will be inlined as base64 URLs to avoid extra http requests. Set to
0 to disable inlining altogether.
If a callback is passed, a boolean can be returned to opt-in or opt-out. If nothing is returned the default logic applies.
Git LFS placeholders are automatically excluded from inlining because they do not contain the content of the file they represent.
::: tip Note
If you specify
build.lib,
build.assetsInlineLimit will be ignored and assets will always be inlined, regardless of file size or being a Git LFS placeholder.
:::
build.cssCodeSplit
Type:
boolean
Default:
true
Enable/disable CSS code splitting. When enabled, CSS imported in async JS chunks will be preserved as chunks and fetched together when the chunk is fetched.
If disabled, all CSS in the entire project will be extracted into a single CSS file.
::: tip Note
If you specify
build.lib,
build.cssCodeSplit will be
false as default.
:::
build.cssTarget
Type:
string | string[]
Default: the same as
build.target
This option allows users to set a different browser target for CSS minification from the one used for JavaScript transpilation.
When
build.cssMinify is
'lightningcss' (the default), this option takes precedence over
css.lightningcss.targets for the minification step.
It should only be used when you are targeting a non-mainstream browser.
One example is Android WeChat WebView, which supports most modern JavaScript features but not the
#RGBA hexadecimal color notation in CSS.
In this case, you need to set
build.cssTarget to
chrome61 to prevent Vite from transforming
rgba() colors into
#RGBA hexadecimal notations.
build.cssMinify
Type:
boolean | 'lightningcss' | 'esbuild'
Default:
'lightningcss', but
false if
build.minify is disabled for client build
This option allows users to override CSS minification specifically instead of defaulting to
build.minify, so you can configure minification for JS and CSS separately. Vite uses Lightning CSS by default to minify CSS. It can be configured using
css.lightningcss. Set the option to
'esbuild' to use esbuild instead.
esbuild must be installed when it is set to
'esbuild'.
npm add -D esbuild
build.sourcemap
Type:
boolean | 'inline' | 'hidden'
Default:
false
Generate production source maps. If
true, a separate sourcemap file will be created. If
'inline', the sourcemap will be appended to the resulting output file as a data URI.
'hidden' works like
true except that the corresponding sourcemap comments in the bundled files are suppressed.
build.chunkImportMap
Type:
boolean
Default:
false
Experimental
Related: Chunk Import Map Optimization
Whether to use import maps feature to optimize chunk caching efficiency.
Note that this option requires
import.meta.resolve support. If you need to support older browsers, check out
@vitejs/plugin-legacy.
build.rolldownOptions
Type:
RolldownOptions
Directly customize the underlying Rolldown bundle. This is the same as options that can be exported from a Rolldown config file and will be merged with Vite's internal Rolldown options. See Rolldown options docs for more details.
Vite overrides Rolldown's default for
preserveEntrySignatures. When this option is not set, Vite uses
false for regular client builds,
'strict' for library builds, and
'allow-extension' for SSR builds.
Instead of
build.rolldownOptions.input, it is recommended to set the top-level
input option, because it will be used in dev as well. If
build.rolldownOptions.input is set, it overrides the top-level
input option for build only.
build.rollupOptions
Type:
RolldownOptions
Deprecated
This option is an alias of
build.rolldownOptions option. Use
build.rolldownOptions option instead.
build.dynamicImportVarsOptions
Type:
{ include?: string | RegExp | (string | RegExp)[], exclude?: string | RegExp | (string | RegExp)[] }
Related: Dynamic Import
Whether to transform dynamic imports with variables.
build.lib
Type:
{ entry?: string | string[] | { [entryAlias: string]: string }, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string | ((format: ModuleFormat, entryName: string) => string), cssFileName?: string }
Related: Library Mode
Build as a library.
entry defaults to the top-level
input option, and one of them is required since the library cannot use HTML as entry.
name is the exposed global variable and is required when
formats includes
'umd' or
'iife'. Default
formats are
['es', 'umd'], or
['es', 'cjs'], if multiple entries are used.
fileName is the name of the package file output, which defaults to the
"name" in
package.json. It can also be defined as a function taking the
format and
entryName as arguments, and returning the file name.
If your package imports CSS,
cssFileName can be used to specify the name of the CSS file output. It defaults to the same value as
fileName if it's set a string, otherwise it also falls back to the
"name" in
package.json.
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: ['src/main.js'],
fileName: (format, entryName) => `my-lib-${entryName}.${format}.js`,
cssFileName: 'my-lib-style',
},
},
})
build.license
Type:
boolean | { fileName?: string }
Default:
false
Related: License
When set to
true, the build will generate a
.vite/license.md file that includes all bundled dependencies' licenses.
If
fileName is passed, it will be used as the license file name relative to the
outDir. If it ends with
.json, the raw JSON metadata will be generated instead and can be used for further processing. For example:
[
{
"name": "dep-1",
"version": "1.2.3",
"identifier": "CC0-1.0",
"text": "CC0 1.0 Universal\n\n..."
},
{
"name": "dep-2",
"version": "4.5.6",
"identifier": "MIT",
"text": "MIT License\n\n..."
}
]
::: tip
If you'd like to reference the license file in the built code, you can use
build.rolldownOptions.output.postBanner to inject a comment at the top of the files. For example:
import { defineConfig } from 'vite'
export default defineConfig({
build: {
license: true,
rolldownOptions: {
output: {
postBanner:
'/* See licenses of bundled dependencies at https://example.com/license.md */',
},
},
},
})
:::
build.manifest
Type:
boolean | string
Default:
false
Related: Backend Integration
Whether to generate a manifest file that contains a mapping of non-hashed asset filenames to their hashed versions, which can then be used by a server framework to render the correct asset links.
When the value is a string, it will be used as the manifest file path relative to
build.outDir. When set to
true, the path would be
.vite/manifest.json.
If you are writing a plugin and need to inspect each output chunk or asset's related CSS and static assets during the build, you can also use
viteMetadata output bundle metadata API.
build.ssrManifest
Type:
boolean | string
Default:
false
Related: Server-Side Rendering
Whether to generate a SSR manifest file for determining style links and asset preload directives in production.
When the value is a string, it will be used as the manifest file path relative to
build.outDir. When set to
true, the path would be
.vite/ssr-manifest.json.
build.ssr
Type:
boolean | string
Default:
false
Related: Server-Side Rendering
Produce SSR-oriented build. The value can be a string to directly specify the SSR entry, or
true, which requires specifying the SSR entry via
input or
build.rolldownOptions.input.
build.emitAssets
Type:
boolean
Default:
false
During non-client builds, static assets aren't emitted as it is assumed they would be emitted as part of the client build. This option allows frameworks to force emitting them in other environments build. It is responsibility of the framework to merge the assets with a post build step.
build.ssrEmitAssets
Type:
boolean
Default:
false
During the SSR build, static assets aren't emitted as it is assumed they would be emitted as part of the client build. This option allows frameworks to force emitting them in both the client and SSR build. It is responsibility of the framework to merge the assets with a post build step. This option will be replaced by
build.emitAssets once Environment API is stable.
build.minify
Type:
boolean | 'oxc' | 'terser' | 'esbuild'
Default:
'oxc' for client build,
false for SSR build
Set to
false to disable minification, or specify the minifier to use. The default is Oxc Minifier which is 30 ~ 90x faster than terser and only 0.5 ~ 2% worse compression. Benchmarks
build.minify: 'esbuild' is deprecated and will be removed in the future.
Note the
build.minify option does not minify whitespaces when using the
'es' format in lib mode, as it removes pure annotations and breaks tree-shaking.
esbuild or Terser must be installed when it is set to
'esbuild' or
'terser' respectively.
npm add -D esbuild
npm add -D terser
build.terserOptions
Type:
TerserOptions
Additional minify options to pass on to Terser.
In addition, you can also pass a
maxWorkers: number option to specify the max number of workers to spawn. Defaults to the number of CPUs minus 1.
build.write
Type:
boolean
Default:
true
Set to
false to disable writing the bundle to disk. This is mostly used in programmatic
build() calls where further post processing of the bundle is needed before writing to disk.
build.emptyOutDir
Type:
boolean
Default:
true if
outDir is inside
root
By default, Vite will empty the
outDir on build if it is inside project root. It will emit a warning if
outDir is outside of root to avoid accidentally removing important files. You can explicitly set this option to suppress the warning. This is also available via command line as
--emptyOutDir.
build.copyPublicDir
Type:
boolean
Default:
true
By default, Vite will copy files from the
publicDir into the
outDir on build. Set to
false to disable this.
build.reportCompressedSize
Type:
boolean
Default:
true
Enable/disable gzip-compressed size reporting. Compressing large output files can be slow, so disabling this may increase build performance for large projects.
build.chunkSizeWarningLimit
Type:
number
Default:
500
Limit for chunk size warnings (in kB). It is compared against the uncompressed chunk size as the JavaScript size itself is related to the execution time.
build.watch
Type:
WatcherOptions
| null
Default:
null
Set to
{} to enable Rolldown watcher. This is mostly used in cases that involve build-only plugins or integrations processes.
::: warning Using Vite on Windows Subsystem for Linux (WSL) 2
There are cases that file system watching does not work with WSL2.
See
server.watch for more details.
:::
Dep Optimization Options
Related: Dependency Pre-Bundling
Unless noted, the options in this section are only applied to the dependency optimizer, which is only used in dev.
optimizeDeps.entries
Type:
string | string[]
By default, Vite will crawl all your
.html files to detect dependencies that need to be pre-bundled (ignoring
node_modules,
build.outDir,
__tests__ and
coverage). If the top-level
input or
build.rolldownOptions.input is specified, Vite will crawl those entry points instead.
If neither of these fit your needs, you can specify custom entries using this option - the value should be a
tinyglobby pattern or array of patterns that are relative from Vite project root. This will overwrite default entries inference. Only
node_modules and
build.outDir folders will be ignored by default when
optimizeDeps.entries is explicitly defined. If other folders need to be ignored, you can use an ignore pattern as part of the entries list, marked with an initial
!.
node_modules will not be ignored for patterns that explicitly include the string
node_modules.
optimizeDeps.exclude
Type:
string[]
Dependencies to exclude from pre-bundling.
:::warning CommonJS
CommonJS dependencies should not be excluded from optimization. If an ESM dependency is excluded from optimization, but has a nested CommonJS dependency, the CommonJS dependency should be added to
optimizeDeps.include. Example:
import { defineConfig } from 'vite'
// ---cut---
export default defineConfig({
optimizeDeps: {
include: ['esm-dep > cjs-dep'],
},
})
:::
optimizeDeps.include
Type:
string[]
By default, linked packages not inside
node_modules are not pre-bundled. Use this option to force a linked package to be pre-bundled.
Experimental: If you're using a library with many deep imports, you can also specify a trailing glob pattern to pre-bundle all deep imports at once. This will avoid constantly pre-bundling whenever a new deep import is used. Give Feedback. For example:
import { defineConfig } from 'vite'
// ---cut---
export default defineConfig({
optimizeDeps: {
include: ['my-lib/components/**/*.vue'],
},
})
optimizeDeps.rolldownOptions
Type:
Omit & { output?: Omit }
Options to pass to Rolldown during the dep scanning and optimization.
Certain options are omitted since changing them would not be compatible with Vite's dep optimization.
plugins are merged with Vite's dep plugin
optimizeDeps.esbuildOptions
Type:
Omit
Deprecated
This option is converted to
optimizeDeps.rolldownOptions internally. Use
optimizeDeps.rolldownOptions instead.
optimizeDeps.force
Type:
boolean
Set to
true to force dependency pre-bundling, ignoring previously cached optimized dependencies.
optimizeDeps.noDiscovery
Type:
boolean
Default:
false
When set to
true, automatic dependency discovery will be disabled and only dependencies listed in
optimizeDeps.include will be optimized. CJS-only dependencies must be present in
optimizeDeps.include during dev.
optimizeDeps.holdUntilCrawlEnd
Experimental: Give Feedback
Type:
boolean
Default:
true
When enabled, it will hold the first optimized deps results until all static imports are crawled on cold start. This avoids the need for full-page reloads when new dependencies are discovered and they trigger the generation of new common chunks. If all dependencies are found by the scanner plus the explicitly defined ones in
include, it is better to disable this option to let the browser process more requests in parallel.
optimizeDeps.disabled
Deprecated
Experimental: Give Feedback
Type:
boolean | 'build' | 'dev'
Default:
'build'
This option is deprecated. As of Vite 5.1, pre-bundling of dependencies during build have been removed. Setting
optimizeDeps.disabled to
true or
'dev' disables the optimizer, and configured to
false or
'build' leaves the optimizer during dev enabled.
To disable the optimizer completely, use
optimizeDeps.noDiscovery: true to disallow automatic discovery of dependencies and leave
optimizeDeps.include undefined or empty.
:::warning
Optimizing dependencies during build time was an experimental feature. Projects trying out this strategy also removed
@rollup/plugin-commonjs using
build.commonjsOptions: { include: [] }. If you did so, a warning will guide you to re-enable it to support CJS only packages while bundling.
:::
optimizeDeps.needsInterop
Experimental
Type:
string[]
Forces ESM interop when importing these dependencies. Vite is able to properly detect when a dependency needs interop, so this option isn't generally needed. However, different combinations of dependencies could cause some of them to be prebundled differently. Adding these packages to
needsInterop can speed up cold start by avoiding full-page reloads. You'll receive a warning if this is the case for one of your dependencies, suggesting to add the package name to this array in your config.
Configuring Vite
When running
vite from the command line, Vite will automatically try to resolve a config file named
vite.config.js inside project root (other JS and TS extensions are also supported).
The most basic config file looks like this:
export default {
// config options
}
Note that to use ES modules syntax in the config file, it should be in a file detected as ESM by Node.js, e.g.
.mjs or
.js with
"type": "module" in closest
package.json.
You can also explicitly specify a config file to use with the
--config CLI option (resolved relative to
cwd):
vite --config my-config.js
Watch an interactive lesson on Scrimba
::: tip CONFIG LOADING
By default, Vite uses Rolldown to bundle the config into a temporary file and load it. If you're using an environment that supports TypeScript (e.g. Node 22.18+), or if you're only writing plain JavaScript, you can specify
--configLoader native to use the environment's native runtime to load the config file.
configLoader: 'native' is planned to become the default in a future major version.
:::
Config Intellisense
Since Vite ships with TypeScript typings, you can leverage your IDE's intellisense with JSDoc type hints:
/** @type {import('vite').UserConfig} */
export default {
// ...
}
Alternatively, you can use the
defineConfig helper which should provide intellisense without the need for JSDoc annotations:
import { defineConfig } from 'vite'
export default defineConfig({
// ...
})
Vite also supports TypeScript config files. You can use
vite.config.ts with the
defineConfig helper function above, or with the
satisfies operator:
import type { UserConfig } from 'vite'
export default {
// ...
} satisfies UserConfig
Conditional Config
If the config needs to conditionally determine options based on the command (
serve or
build), the mode being used, if it's an SSR build (
isSsrBuild), or is previewing the build (
isPreview), it can export a function instead:
import { defineConfig } from 'vite'
// ---cut---
export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
if (command === 'serve') {
return {
// dev specific config
}
} else {
// command === 'build'
return {
// build specific config
}
}
})
It is important to note that in Vite's API the
command value is
serve during dev (in the cli
vite,
vite dev, and
vite serve are aliases), and
build when building for production (
vite build).
isSsrBuild and
isPreview are additional optional flags to differentiate the kind of
build and
serve commands respectively. Some tools that load the Vite config may not support these flags and will pass
undefined instead. Hence, it's recommended to use explicit comparison against
true and
false.
Async Config
If the config needs to call async functions, it can export an async function instead. And this async function can also be passed through
defineConfig for improved intellisense support:
import { defineConfig } from 'vite'
// ---cut---
export default defineConfig(async ({ command, mode }) => {
const data = await asyncFunction()
return {
// vite config
}
})
Using Environment Variables in Config
Environment variables available while the config itself is being evaluated are only those that already exist in the current process environment (
process.env). Vite deliberately defers loading any
.env* files until after the user config has been resolved because the set of files to load depends on config options like
root and
envDir, and also on the final
mode.
This means: variables defined in
.env,
.env.local,
.env.[mode], or
.env.[mode].local are not automatically injected into
process.env while your
vite.config.* is running. They are automatically loaded later and exposed to application code via
import.meta.env (with the default
VITE_ prefix filter) exactly as documented in Env Variables and Modes. So if you only need to pass values from
.env* files to the app, you don't need to call anything in the config.
If, however, values from
.env* files must influence the config itself (for example to set
server.port, conditionally enable plugins, or compute
define replacements), you can load them manually using the exported
loadEnv helper.
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the
// `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
return {
define: {
// Provide an explicit app-level constant derived from an env var.
__APP_ENV__: JSON.stringify(env.APP_ENV),
},
// Example: use an env var to set the dev server port conditionally.
server: {
port: env.APP_PORT ? Number(env.APP_PORT) : 5173,
},
}
})
Debugging the Config File in VS Code
For the most reliable debugging experience, use the native config loader when starting Vite:
vite --configLoader native
The native loader executes the original config file directly, so breakpoints in the config file and in plugin hooks such as
transform map to the original source. It requires a runtime that supports the syntax used by your config file, such as Node.js 22.18+ for TypeScript files.
When using
--configLoader bundle (the current default, though
native is planned to become the default in a future major version), Vite generates an inline source map and writes the bundled config to
node_modules/.vite-temp before loading it. If you need to use the bundle loader, add the temporary directory for the JavaScript Debug Terminal in
.vscode/settings.json:
{
"debug.javascript.terminalOptions": {
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**",
"**/node_modules/.vite-temp/**"
]
}
}
This setting only applies to the JavaScript Debug Terminal, it does not affect launch configurations started from the Run and Debug view. To support this for the Run and Debug view, add the temporary directory in
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Vite",
"runtimeExecutable": "npm",
"runtimeArgs": ["exec", "vite", "--configLoader", "bundle"],
"console": "integratedTerminal",
"sourceMaps": true,
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**",
"**/node_modules/.vite-temp/**"
]
}
]
}
Preview Options
Unless noted, the options in this section are only applied to preview.
preview.host
Type:
string | boolean
Default:
server.host
Specify which IP addresses the server should listen on.
Set this to
0.0.0.0 or
true to listen on all addresses, including LAN and public addresses.
This can be set via the CLI using
--host 0.0.0.0 or
--host.
::: tip NOTE
There are cases when other servers might respond instead of Vite.
See
server.host for more details.
:::
preview.allowedHosts
Type:
string[] | true
Default:
server.allowedHosts
The hostnames that Vite is allowed to respond to.
See
server.allowedHosts for more details.
preview.port
Type:
number
Default:
4173
Specify server port. Note if the port is already being used, Vite will automatically try the next available port so this may not be the actual port the server ends up listening on.
Example:
export default defineConfig({
server: {
port: 3030,
},
preview: {
port: 8080,
},
})
preview.strictPort
Type:
boolean
Default:
server.strictPort
Set to
true to exit if port is already in use, instead of automatically trying the next available port.
preview.https
Type:
https.ServerOptions
Default:
server.https
Enable TLS + HTTP/2.
See
server.https for more details.
preview.open
Type:
boolean | string
Default:
server.open
Automatically open the app in the browser on server start. When the value is a string, it will be used as the URL's pathname. If you want to open the server in a specific browser you like, you can set the env
process.env.BROWSER (e.g.
firefox). You can also set
process.env.BROWSER_ARGS to pass additional arguments (e.g.
--incognito).
BROWSER and
BROWSER_ARGS are also special environment variables you can set in the
.env file to configure it. See the
open package for more details.
preview.proxy
Type:
Record
Default:
server.proxy
Configure custom proxy rules for the preview server. Expects an object of
{ key: options } pairs. If the key starts with
^, it will be interpreted as a
RegExp. The
configure option can be used to access the proxy instance.
Uses
http-proxy-3. Full options here.
preview.cors
Type:
boolean | CorsOptions
Default:
server.cors
Configure CORS for the preview server.
See
server.cors for more details.
preview.headers
Type:
OutgoingHttpHeaders
Specify server response headers.
Server Options
Unless noted, the options in this section are only applied to dev.
server.host
Type:
string | boolean
Default:
'localhost'
Specify which IP addresses the server should listen on.
Set this to
0.0.0.0 or
true to listen on all addresses, including LAN and public addresses.
This can be set via the CLI using
--host 0.0.0.0 or
--host.
::: tip NOTE
There are cases when other servers might respond instead of Vite.
The first case is when
localhost is used. Node.js's
dns.setDefaultResultOrder changes how DNS-resolved addresses are ordered, and browsers may use a different resolved address than the one Vite is listening to. Vite prints the resolved address when it differs.
The second case is when wildcard hosts (e.g.
0.0.0.0) are used. This is because servers listening on non-wildcard hosts take priority over those listening on wildcard hosts.
:::
::: tip Accessing the server on WSL2 from your LAN
When running Vite on WSL2, it is not sufficient to set
host: true to access the server from your LAN.
See the WSL document for more details.
:::
server.allowedHosts
Type:
string[] | true
Default:
[]
The hostnames that Vite is allowed to respond to.
localhost and domains under
.localhost and all IP addresses are allowed by default.
When using HTTPS, this check is skipped.
If a string starts with
., it will allow that hostname without the
. and all subdomains under the hostname. For example,
.example.com will allow
example.com,
foo.example.com, and
foo.bar.example.com. If set to
true, the server is allowed to respond to requests for any hosts.
::: details What hosts are safe to be added?
Hosts that you have control over which IP addresses they resolve to are safe to add to the list of allowed hosts.
For example, if you own a domain
vite.dev, you can add
vite.dev and
.vite.dev to the list. If you don't own that domain and you cannot trust the owner of that domain, you should not add it.
Especially, you should never add Top-Level Domains like
.com to the list. This is because anyone can purchase a domain like
example.com and control the IP address it resolves to.
:::
::: danger
Setting
server.allowedHosts to
true allows any website to send requests to your dev server through DNS rebinding attacks, allowing them to download your source code and content. We recommend always using an explicit list of allowed hosts. See GHSA-vg6x-rcgg-rjx6 for more details.
:::
::: details Configure via environment variable
You can set the environment variable
__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS to add additional allowed hosts. Use commas to separate multiple hosts (e.g.,
host1.example.com,host2.example.com).
:::
server.port
Type:
number
Default:
5173
Specify server port. Note if the port is already being used, Vite will automatically try the next available port so this may not be the actual port the server ends up listening on.
server.strictPort
Type:
boolean
Set to
true to exit if port is already in use, instead of automatically trying the next available port.
server.https
Type:
https.ServerOptions
Enable TLS + HTTP/2. The value is an options object passed to
https.createServer().
A valid certificate is needed. For a basic setup, you can add @vitejs/plugin-basic-ssl to the project plugins, which will automatically create and cache a self-signed certificate. But we recommend creating your own certificates.
server.open
Type:
boolean | string
Automatically open the app in the browser on server start. When the value is a string, it will be used as the URL's pathname. If you want to open the server in a specific browser you like, you can set the env
process.env.BROWSER (e.g.
firefox). You can also set
process.env.BROWSER_ARGS to pass additional arguments (e.g.
--incognito).
BROWSER and
BROWSER_ARGS are also special environment variables you can set in the
.env file to configure it. See the
open package for more details.
Example:
export default defineConfig({
server: {
open: '/docs/index.html',
},
})
server.proxy
Type:
Record
Configure custom proxy rules for the dev server. Expects an object of
{ key: options } pairs. Any requests whose request path starts with that key will be proxied to the specified target. If the key starts with
^, it will be interpreted as a
RegExp. The
configure option can be used to access the proxy instance. If a request matches any of the configured proxy rules, the request won't be transformed by Vite.
Note that if you are using non-relative
base, you must prefix each key with that
base.
Extends
http-proxy-3. Additional options are here.
In some cases, you might also want to configure the underlying dev server (e.g. to add custom middlewares to the internal connect app). In order to do that, you need to write your own plugin and use configureServer function.
Example:
export default defineConfig({
server: {
proxy: {
// string shorthand:
// http://localhost:5173/foo
// -> http://localhost:4567/foo
'/foo': 'http://localhost:4567',
// with options:
// http://localhost:5173/api/bar
// -> http://jsonplaceholder.typicode.com/bar
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
// with RegExp:
// http://localhost:5173/fallback/
// -> http://jsonplaceholder.typicode.com/
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/fallback/, ''),
},
// Using the proxy instance
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
configure: (proxy, options) => {
// proxy will be an instance of 'http-proxy-3'
},
},
// Proxying websockets or socket.io:
// ws://localhost:5173/socket.io
// -> ws://localhost:5174/socket.io
// Exercise caution using `rewriteWsOrigin` as it can leave the
// proxying open to CSRF attacks.
'/socket.io': {
target: 'ws://localhost:5174',
ws: true,
rewriteWsOrigin: true,
},
},
},
})
::: warning Origin check for WebSockets
Vite does not check the origin of WebSocket requests before proxying. The proxy target is expected to check the
Origin header or other checks. Note that the
rewriteWsOrigin option will rewrite the origin to the target origin and will cause the origin check to be bypassed.
:::
server.cors
Type:
boolean | CorsOptions
Default:
{ origin: /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/ } (allows localhost,
127.0.0.1 and
::1)
Configure CORS for the dev server. Pass an options object to fine tune the behavior or
true to allow any origin.
::: danger
Setting
server.cors to
true allows any website to send requests to your dev server and download your source code and content. We recommend always using an explicit list of allowed origins.
:::
server.headers
Type:
OutgoingHttpHeaders
Specify server response headers.
server.hmr
Type:
boolean | { overlay?: boolean }
Disable or configure HMR behavior.
Set
server.hmr.overlay to
false to disable the server error overlay.
::: warning Deprecated Options
The WebSocket-related options (
protocol,
host,
port,
path,
clientPort,
timeout,
server) are deprecated. Use
server.ws instead. These options are automatically synced, so existing configurations will continue to work.
:::
server.ws
Type:
false | { protocol?: string, host?: string, port?: number, path?: string, timeout?: number, clientPort?: number, server?: Server }
Configure WebSocket connection options. Set to
false to disable the WebSocket connection entirely.
protocol - WebSocket protocol (
ws or
wss)
host - WebSocket server host
port - WebSocket server port
path - WebSocket path
clientPort - Override the port on the client side, allowing you to serve the websocket on a different port than the client code looks for it on
timeout - Connection timeout in milliseconds (default: 30000)
server - Use a custom HTTP server for WebSocket connections
When
server.ws.server is defined, Vite will process the WebSocket connection requests through the provided server. If not in middleware mode, Vite will attempt to process WebSocket connection requests through the existing server. This can be helpful when using self-signed certificates or when you want to expose Vite over a network on a single port.
export default defineConfig({
server: {
ws: {
protocol: 'wss',
host: 'localhost',
port: 3001,
},
},
})
Check out
vite-setup-catalogue for some examples.
::: tip NOTE
With the default configuration, reverse proxies in front of Vite are expected to support proxying WebSocket. If the Vite HMR client fails to connect WebSocket, the client will fall back to connecting the WebSocket directly to the Vite HMR server bypassing the reverse proxies:
Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-ws to remove the previous connection error.
The error that appears in the Browser when the fallback happens can be ignored. To avoid the error by directly bypassing reverse proxies, you could either:
configure the reverse proxy to proxy WebSocket too
set
server.strictPort = true and set
server.ws.clientPort to the same value with
server.port
set
server.ws.port to a different value from
server.port
:::
server.forwardConsole
Type:
boolean | { unhandledErrors?: boolean, logLevels?: ('error' | 'warn' | 'info' | 'log' | 'debug')[] }
Default: auto (
true when an AI coding agent is detected based on
std-env, otherwise
false)
Forward browser runtime events to the Vite server console during development.
true enables forwarding unhandled errors and
console.error /
console.warn logs.
unhandledErrors controls forwarding uncaught exceptions and unhandled promise rejections.
logLevels controls which
console.* calls are forwarded.
For example:
export default defineConfig({
server: {
forwardConsole: {
unhandledErrors: true,
logLevels: ['warn', 'error'],
},
},
})
When unhandled errors are forwarded, they are logged in the server terminal with enhanced formatting, for example:
1:18:38 AM [vite] (client) [Unhandled error] Error: this is test error
> testError src/main.ts:20:8
18|
19| function testError() {
20| throw new Error('this is test error')
| ^
21| }
22|
> HTMLButtonElement. src/main.ts:6:2
server.warmup
Type:
{ clientFiles?: string[], ssrFiles?: string[] }
Related: Warm Up Frequently Used Files
Warm up files to transform and cache the results in advance. This improves the initial page load during server starts and prevents transform waterfalls.
clientFiles are files that are used in the client only, while
ssrFiles are files that are used in SSR only. They accept an array of file paths or
tinyglobby patterns relative to the
root.
Make sure to only add files that are frequently used to not overload the Vite dev server on startup.
export default defineConfig({
server: {
warmup: {
clientFiles: ['./src/components/*.vue', './src/utils/big-utils.js'],
ssrFiles: ['./src/server/modules/*.js'],
},
},
})
server.watch
Type:
object | null
File system watcher options to pass on to chokidar.
When bundled-dev mode is enabled, Rolldown watch options (for example,
usePolling,
pollInterval,
useDebounce,
debounceDuration,
include,
exclude) are also accepted. The chokidar-only options are still used by the chokidar watcher, which keeps watching files outside the module graph, such as config file dependencies and env files.
The Vite server watcher watches the
root and skips the
.git/,
node_modules/,
test-results/, and Vite's
cacheDir and
build.outDir directories by default. When updating a watched file, Vite will apply HMR and update the page only if needed.
If set to
null, no files will be watched.
server.watcher will provide a compatible event emitter, but calling
add or
unwatch will have no effect.
::: warning Watching files in
node_modules
It's currently not possible to watch files and packages in
node_modules. For further progress and workarounds, you can follow issue #8619.
:::
::: warning Using Vite on Windows Subsystem for Linux (WSL) 2
When running Vite on WSL2, file system watching does not work when a file is edited by Windows applications (non-WSL2 process). This is due to a WSL2 limitation. This also applies to running on Docker with a WSL2 backend.
To fix it, you could either:
Recommended: Use WSL2 applications to edit your files.
It is also recommended to move the project folder outside of a Windows filesystem. Accessing Windows filesystem from WSL2 is slow. Removing that overhead will improve performance.
Set
{ usePolling: true }.
Note that
usePolling leads to high CPU utilization.
:::
server.middlewareMode
Type:
boolean | { server: http.Server }
Default:
false
Create Vite server in middleware mode.
If proxy is setup for WebSocket, the
server should be provided to bind the proxy correctly.
Related: appType, SSR - Setting Up the Dev Server
Example:
import express from 'express'
import { createServer as createViteServer } from 'vite'
async function createServer() {
const app = express()
// Create Vite server in middleware mode
const vite = await createViteServer({
server: { middlewareMode: true },
// don't include Vite's default HTML handling middlewares
appType: 'custom',
})
// Use vite's connect instance as middleware
app.use(vite.middlewares)
app.use('*', async (req, res) => {
// Since `appType` is `'custom'`, should serve response here.
// Note: if `appType` is `'spa'` or `'mpa'`, Vite includes middlewares
// to handle HTML requests and 404s so user middlewares should be added
// before Vite's middlewares to take effect instead
})
}
createServer()
server.fs.strict
Type:
boolean
Default:
true (enabled by default since Vite 2.7)
Restrict serving files outside of workspace root.
server.fs.allow
Type:
string[]
Restrict files that could be served via
/@fs/. When
server.fs.strict is set to
true, accessing files outside this directory list that aren't imported from an allowed file will result in a 403.
Both directories and files can be provided.
Vite will search for the root of the potential workspace and use it as default. A valid workspace met the following conditions, otherwise will fall back to the project root.
contains
workspaces field in
package.json
contains one of the following file
lerna.json
pnpm-workspace.yaml
Accepts a path to specify the custom workspace root. Could be a absolute path or a path relative to project root. For example:
export default defineConfig({
server: {
fs: {
// Allow serving files from one level up to the project root
allow: ['..'],
},
},
})
When
server.fs.allow is specified, the auto workspace root detection will be disabled. To extend the original behavior, a utility
searchForWorkspaceRoot is exposed:
import { defineConfig, searchForWorkspaceRoot } from 'vite'
export default defineConfig({
server: {
fs: {
allow: [
// search up for workspace root
searchForWorkspaceRoot(process.cwd()),
// your custom rules
'/path/to/custom/allow_directory',
'/path/to/custom/allow_file.demo',
],
},
},
})
server.fs.deny
Type:
string[]
Default:
['.env', '.env.*', '*.{crt,pem,key,p12,pfx,cer,der}', '.npmrc', '.yarnrc.yml', '**/.git/**']
Blocklist for sensitive files being restricted to be served by Vite dev server. This will have higher priority than
server.fs.allow. picomatch patterns are supported.
::: tip NOTE
This blocklist does not apply to the public directory. All files in the public directory are served without any filtering, since they are copied directly to the output directory during build.
:::
::: tip NOTE
The deny filter is applied against the module id and the id with query parameters stripped. Since a plugin can read files from any files in its load hook (including resolving symlinks to denied paths), Vite cannot guarantee that a denied file is inaccessible through an alternative path. If you have an alternative path, include it in the deny list as well.
:::
server.origin
Type:
string
Defines the origin of the generated asset URLs during development.
export default defineConfig({
server: {
origin: 'http://127.0.0.1:8080',
},
})
server.sourcemapIgnoreList
Type:
false | (sourcePath: string, sourcemapPath: string) => boolean
Default:
(sourcePath) => /(?:^|[\\/])node_modules(?:[\\/]|$)/.test(sourcePath)
Whether or not to ignore source files in the server sourcemap, used to populate the
x_google_ignoreList source map extension.
server.sourcemapIgnoreList is the equivalent of
build.rolldownOptions.output.sourcemapIgnoreList for the dev server. A difference between the two config options is that the Rolldown function is called with a relative path for
sourcePath while
server.sourcemapIgnoreList is called with an absolute path. During dev, most modules have the map and the source in the same folder, so the relative path for
sourcePath is the file name itself. In these cases, absolute paths make it convenient to be used instead.
By default, it excludes all paths that contain
node_modules as a path segment. You can pass
false to disable this behavior, or, for full control, a function that takes the source path and sourcemap path and returns whether to ignore the source path.
export default defineConfig({
server: {
// This is the default value, and will add all files that have
// node_modules as a path segment to the ignore list.
sourcemapIgnoreList(sourcePath, sourcemapPath) {
return /(?:^|[\\/])node_modules(?:[\\/]|$)/.test(sourcePath)
},
},
})
::: tip Note
server.sourcemapIgnoreList and
build.rolldownOptions.output.sourcemapIgnoreList need to be set independently.
server.sourcemapIgnoreList is a server only config and doesn't get its default value from the defined Rolldown options.
:::
Shared Options
Unless noted, the options in this section are applied to all dev, build, and preview.
root
Type:
string
Default:
process.cwd()
Project root directory (where
index.html is located). Can be an absolute path, or a path relative to the current working directory.
See Project Root for more details.
base
Type:
string
Default:
/
Related:
server.origin
Base public path when served in development or production. Valid values include:
Absolute URL pathname, e.g.
/foo/
Full URL, e.g.
https://bar.com/foo/ (The origin part won't be used in development so the value is the same as
/foo/)
Empty string or
./ (for embedded deployment)
See Public Base Path for more details.
mode
Type:
string
Default:
'development' for serve,
'production' for build
Specifying this in config will override the default mode for both serve and build. This value can also be overridden via the command line
--mode option.
See Env Variables and Modes for more details.
input
Type:
string | string[] | { [entryAlias: string]: string }
Entry points of your application, resolved relative to the project root. This works as the default value for
build.rolldownOptions.input,
build.lib.entry,
build.ssr (if
true), and
optimizeDeps.entries when those are not set explicitly.
This is useful when your application does not use an
index.html entry, so you only need to declare the entry once instead of repeating it across the options above.
import { defineConfig } from 'vite'
export default defineConfig({
input: 'src/main.ts',
})
define
Type:
Record
Define global constant replacements. Entries will be defined as globals during dev and statically replaced during build.
Vite uses Oxc's define feature to perform replacements, so value expressions must be a string that contains a JSON-serializable value (null, boolean, number, string, array, or object) or a single identifier. For non-string values, Vite will automatically convert it to a string with
JSON.stringify.
Example:
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify('v1.0.0'),
__API_URL__: 'window.__backend_api_url',
},
})
::: tip NOTE
For TypeScript users, make sure to add the type declarations in the
vite-env.d.ts file to get type checks and Intellisense.
Example:
// vite-env.d.ts
declare const __APP_VERSION__: string
:::
plugins
Type:
(Plugin | Plugin[] | Promise)[]
Array of plugins to use. Falsy plugins are ignored and arrays of plugins are flattened. If a promise is returned, it would be resolved before running. See Plugin API for more details on Vite plugins.
publicDir
Type:
string | false
Default:
"public"
Directory to serve as plain static assets. Files in this directory are served at
/ during dev and copied to the root of
outDir during build, and are always served or copied as-is without transform. The value can be either an absolute file system path or a path relative to project root.
Defining
publicDir as
false disables this feature.
See The
public Directory for more details.
cacheDir
Type:
string
Default:
"node_modules/.vite"
Directory to save cache files. Files in this directory are pre-bundled deps or some other cache files generated by vite, which can improve the performance. You can use
--force flag or manually delete the directory to regenerate the cache files. The value can be either an absolute file system path or a path relative to project root. Default to
.vite when no
package.json is detected.
resolve.alias
Type:
Record | Array<{ find: string | RegExp, replacement: string }>
Defines aliases used to replace values in
import or
require statements. This works similar to
@rollup/plugin-alias.
The order of the entries is important, in that the first defined rules are applied first.
When aliasing to file system paths, always use absolute paths. Relative alias values will be used as-is and will not be resolved into file system paths.
More advanced custom resolution can be achieved through plugins.
::: warning Using with SSR
If you have configured aliases for SSR externalized dependencies, you may want to alias the actual
node_modules packages. Both Yarn and pnpm support aliasing via the
npm: prefix.
:::
Object Format (
Record)
The Object format allows specifying aliases as a key, and the corresponding value as the actual import value. For example:
resolve: {
alias: {
utils: '../../../utils',
'batman-1.0.0': './joker-1.5.0'
}
}
Array Format (
Array<{ find: string | RegExp, replacement: string }>)
The Array format allows specifying aliases as objects, which can be useful for complex key/value pairs.
resolve: {
alias: [
{ find: 'utils', replacement: '../../../utils' },
{ find: 'batman-1.0.0', replacement: './joker-1.5.0' },
]
}
When
find is a regular expression, the
replacement can use replacement patterns, such as
$1. For example, to remove extensions with another, a pattern like the following might be used:
{ find:/^(.*)\.js$/, replacement: '$1.alias' }
resolve.dedupe
Type:
string[]
If you have duplicated copies of the same dependency in your app (likely due to hoisting or linked packages in monorepos), use this option to force Vite to always resolve listed dependencies to the same copy (from project root).
:::warning SSR + ESM
For SSR builds, deduplication does not work for ESM build outputs configured from
build.rolldownOptions.output. A workaround is to use CJS build outputs until ESM has better plugin support for module loading.
:::
resolve.conditions
Type:
string[]
Default:
['module', 'browser', 'development|production'] (
defaultClientConditions)
Additional allowed conditions when resolving Conditional Exports from a package.
A package with conditional exports may have the following
exports field in its
package.json:
{
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js"
}
}
}
Here,
import and
require are "conditions". Conditions can be nested and should be specified from most specific to least specific.
development|production is a special value that is replaced with
production or
development depending on the value of
process.env.NODE_ENV. It is replaced with
production when
process.env.NODE_ENV === 'production' and
development otherwise.
Note that
import,
require,
default conditions are always applied if the requirements are met.
In addition, the
style condition is applied when resolving style imports, e.g.
@import 'my-library'. For some CSS pre-processors, their corresponding conditions are also applied, i.e.
sass for Sass and
less for Less.
resolve.mainFields
Type:
string[]
Default:
['browser', 'module', 'jsnext:main', 'jsnext'] (
defaultClientMainFields)
List of fields in
package.json to try when resolving a package's entry point. Note this takes lower precedence than conditional exports resolved from the
exports field: if an entry point is successfully resolved from
exports, the main field will be ignored.
resolve.extensions
Type:
string[]
Default:
['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']
List of file extensions to try for imports that omit extensions. Note it is NOT recommended to omit extensions for custom import types (e.g.
.vue) since it can interfere with IDE and type support.
resolve.preserveSymlinks
Type:
boolean
Default:
false
Enabling this setting causes vite to determine file identity by the original file path (i.e. the path without following symlinks) instead of the real file path (i.e. the path after following symlinks).
Related: esbuild#preserve-symlinks, webpack#resolve.symlinks
resolve.tsconfigPaths
Type:
boolean
Default:
false
Enables the tsconfig paths resolution feature.
paths option in
tsconfig.json will be used to resolve imports. See Features for more details.
paths only applies to a file matched by a
tsconfig.json through its
files or
include. Non-JS extension files should be explicitly listed in them, since a bare
"src" or
"**/*"
include only matches TS/JS extensions, aligning with TypeScript's behavior. For example, to use a
paths alias inside a CSS file (such as
@import '@/foo.css'), list those files in
files, or add an explicit extension to
include:
{
"include": ["src", "src/**/*.css", "src/**/*.scss"]
}
::: warning Less is not supported
resolve.tsconfigPaths does not apply inside
.less files. Less only gives Vite the importing file's directory, not the file itself, so Vite cannot find the
tsconfig.json that matches it. Use a relative path or
resolve.alias for
@import in Less.
:::
html.cspNonce
Type:
string
Related: Content Security Policy (CSP)
A nonce value placeholder that will be used when generating script / style tags. Setting this value will also generate a meta tag with nonce value.
html.additionalAssetSources
Type:
Record
interface HtmlAssetSource {
srcAttributes?: string[]
srcsetAttributes?: string[]
filter?: (data: {
key: string
value: string
attributes: Record
}) => boolean
}
Define additional HTML elements and attributes to be treated as asset sources. This extends the built-in list that includes standard elements like
,