Since its earliest versions, Vite has relied on two tools: esbuild for development and Rollup for production builds. Vite 8.0, published on 12 March after a beta that began in December, replaces both with one bundler, Rolldown. The facts below come from the Vite 8 announcement and the migration guide published with it.
If your app was scaffolded with npm create vue@latest, upgrade now: it takes four version numbers in package.json and no config change. Two cases need more care. A config that splits chunks with the object form of manualChunks must be rewritten, and a Nuxt app should stay on the Vite that Nuxt installs.
What shipped
Rolldown is a bundler written in Rust by the VoidZero team. It supports the same plugin API as Rollup and Vite, so @vitejs/plugin-vue and most other plugins keep working. Around it, Vite now uses Oxc, the compiler project from the same team: Oxc transforms TypeScript and JSX where esbuild used to, and the Oxc minifier shrinks your JavaScript. Lightning CSS minifies stylesheets by default.
The announcement gives these numbers. In benchmarks Rolldown is 10 to 30 times faster than Rollup and matches esbuild. Companies that tested the preview reported shorter production builds: Linear went from 46 seconds to 6, Ramp cut build time by 57 percent, Mercedes-Benz.io by up to 38 percent and Beehiiv by 64 percent. A small Vue app will not save that much, because its build already takes a few seconds. A large one will notice.
The other items in the announcement:
- Node.js 20.19+ or 22.12+, the same as Vite 7. Those versions can
require()an ES module without a flag, which lets Vite ship as ESM only. - A
devtoolsoption that enables Vite Devtools, a new tool for inspecting what the build does. resolve.tsconfigPaths, which reads thepathsaliases from yourtsconfig.json.- Built-in support for TypeScript's
emitDecoratorMetadata, with no extra plugin. .wasm?initimports now work in server-side rendering.server.forwardConsole, which prints browser console errors in the terminal that runsvite.
The install is larger: about 15 MB more than Vite 7. Roughly 10 MB is Lightning CSS, which moved from an optional peer dependency to a normal one. Roughly 5 MB is the Rolldown binary, which the team says favours speed over size.
What a create-vue project changes
On 17 March, npm create vue@latest runs create-vue 3.22.0, and it still scaffolds Vite 7.3. Moving to 8 is a manual step. The generated vite.config.ts sets only plugins and a resolve.alias for @. Neither touches esbuild or Rollup options, so the file needs no edit.
The changes all live in package.json. After the upgrade, the build-related lines look like this:
{
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.5",
"vite": "^8.0.0",
"vite-plugin-vue-devtools": "^8.1.0",
"vitest": "^4.1.0"
}
}
The two plugin lines move to releases that list ^8.0.0 in their peer range: @vitejs/plugin-vue 6.0.5, published less than an hour after Vite 8, and vite-plugin-vue-devtools 8.1.0, the Vue DevTools plugin, released on 13 March.
The Vitest line matters most. Vitest 4.0 depends on Vite 6 or 7, so on 4.0 your tests would quietly run on a second copy of Vite 7 while your app builds with Vite 8. Vitest 4.1, also published on 12 March, accepts Vite 8. If you use @vitest/coverage-v8 or @vitest/ui, move them to 4.1 too, because they must match Vitest exactly.
Old esbuild and Rollup options keep working
Projects that customised the build used to set options named after the two old tools. Vite 8 converts most of them automatically, so the build keeps working while you rename them. The migration guide lists the mapping:
build.rollupOptionsbecomesbuild.rolldownOptions. The old name still works as an alias.- The
esbuildoption becomesoxc:esbuild.definemaps tooxc.define,esbuild.jsxInjecttooxc.jsxInject, and so on. optimizeDeps.esbuildOptionsbecomesoptimizeDeps.rolldownOptions.build.minify: 'esbuild'andbuild.cssMinify: 'esbuild'still work, but only after you install esbuild yourself, because Vite no longer depends on it.
Do not wait for the terminal to list what needs renaming. Vite 8.0.0 prints a deprecation warning for optimizeDeps.esbuildOptions, but it converts your own build.rollupOptions and most esbuild settings without a message, even though both are deprecated. Search your vite.config.ts for rollupOptions and esbuild and rename them yourself.
Replace object-form manualChunks with codeSplitting
One common setting is not translated. Many Vue projects use the object form of manualChunks to put Vue, Vue Router and Pinia in a chunk of their own, so that a change to your components does not change the file users have cached. Vite 8 no longer supports the object form, and the option's type now accepts only a function, so TypeScript flags it too ('vue' does not exist in type 'ManualChunksFunction'):
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
},
},
},
},
})
The function form still runs but is deprecated. The replacement is Rolldown's codeSplitting option, which takes a list of groups, each with a name and a test:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
rolldownOptions: {
output: {
codeSplitting: {
groups: [{ name: 'vue', test: /node_modules[\\/](@vue|vue|vue-router|pinia)[\\/]/ }],
},
},
},
},
})
The [\\/] in the pattern matches both kinds of slash, so it also works on Windows; Rolldown's docs recommend that form. The @vue entry catches the packages Vue is made of, such as @vue/runtime-dom. If you tried the beta and wrote advancedChunks, rename it too: the Rolldown release candidate inside Vite 8.0 marks advancedChunks as deprecated in favour of codeSplitting.
Which new options to turn on
server.forwardConsole is the one to try first. By default it switches itself on only when Vite detects an AI coding agent. Set it yourself and browser errors and warnings appear in the terminal next to your build output:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
forwardConsole: {
unhandledErrors: true,
logLevels: ['warn', 'error'],
},
},
})
Vue prints its development warnings, such as [Vue warn]: Failed to resolve component, through console.warn, so with this setting they reach the terminal without opening the browser's console.
Leave resolve.tsconfigPaths off in a create-vue project. The scaffold already defines @ twice, once in vite.config.ts for Vite and once in tsconfig.app.json for the editor, and the Vite docs say the option has a performance cost. The exception: if you installed the vite-tsconfig-paths plugin, Vite 8.0.0 prints a warning when it finds it. Remove the plugin and set resolve.tsconfigPaths: true instead.
The devtools option is marked experimental and only works in build mode for now. It needs a separate package, @vitejs/devtools, and Vite 8.0.0 declares support only for that package's alpha builds, not the 0.1 releases now on npm. It is not the Vue DevTools you already use. Skip it for the moment.
How to upgrade
Check Node first: node --version must print 20.19 or a later 20.x release, or 22.12 or later. Then make sure the build and the tests pass on Vite 7.3, and write down the build time and the sizes of the files in dist/assets. That way every difference after the upgrade belongs to the upgrade.
Next, install the new versions and run the same checks:
npm install -D vite@8 @vitejs/plugin-vue@6 vite-plugin-vue-devtools@8 vitest@4
npx vite --version
npm run build
npm run test:unit -- --run
npm run preview
npx vite --version confirms that Vite 8 is the one installed. The -- in npm run test:unit -- --run passes --run on to Vitest, which then runs the tests once instead of watching for changes. In the preview, click through the routes that load pages lazily and the heaviest screens. Those are where a change in chunking or minification shows up.
For a large or unusual project, the announcement recommends a gradual path: first swap vite for the rolldown-vite package on Vite 7, which changes only the bundler, then move to Vite 8. Any failure then tells you whether the bundler or something else caused it.
Nuxt apps are different. Nuxt brings its own Vite, and Nuxt 4.4, released the same day, still depends on Vite 7.3 through @nuxt/vite-builder. Do not add vite@8 to a Nuxt project yourself.
Behaviour changes to test before you deploy
The migration guide lists a few changes that alter behaviour rather than config:
- The default browser target moves up: Chrome and Edge 107 to 111, Firefox 104 to 114, Safari 16.0 to 16.4. If you support older browsers, set
build.targetyourself. - The default import from a CommonJS package now follows one rule in development and production. If a package breaks,
legacy.inconsistentCjsInterop: truerestores the old behaviour while you report it to the package author. - Oxc and esbuild make slightly different assumptions when minifying. If production misbehaves and development does not, build once with
build.minify: 'esbuild'(and esbuild installed) to find out whether the minifier is the cause. - Lightning CSS lowers more syntax for older browsers, so your CSS bundle may grow slightly.
@vitejs/plugin-legacycan no longer transform to ES5 and below. If you ship to very old browsers, wait.