Migration from v7
New Features
Temporary section
This section will be moved to the release post before the stable release.
Built-in tsconfig paths Support
Vite 8 now has built-in tsconfig paths support, thanks to Oxc Resolver. This is not enabled by default, because it has a performance cost and is discouraged by the TypeScript team to use this option to change the behavior of the external tools. While having that caveat, you can enable it by setting resolve.tsconfigPaths to true.
The tsconfig.json in the closest parent directory will be used. For more details about what tsconfig.json is used, see the Features page.
emitDecoratorMetadata Support
Vite 8 now has built-in support for TypeScript's emitDecoratorMetadata option, thanks to Oxc Transformer. If you have emitDecoratorMetadata set to true in your tsconfig, this feature will be enabled automatically.
Note that this transformation has some limitations as the full support requires the full type inference by TypeScript compiler, which is not supported. See Oxc Transformer's documentation for more details.
Default Browser Target change
TODO: This change is not implemented yet, but will be implemented before stable release.
The default browser value of build.target, 'baseline-widely-available', is updated to a newer browser.
- Chrome 107 → 111
- Edge 107 → 111
- Firefox 104 → 114
- Safari 16.0 → 16.4
These browser versions align with Baseline Widely Available feature sets as of 2026-01-01. In other words, they were all released before 2026-01-01.
Rolldown Integration
Vite 8 uses Oxc based tools instead of esbuild and Rollup.
Gradual migration
rolldown-vite package implements Vite 7 with Rolldown integration, but without the other Vite 8 changes. This can be used as a intermediate step to migrate to Vite 8. See the Rolldown Integration guide in the Vite 7 docs to switch to rolldown-vite from Vite 7.
For users migrating from rolldown-vite to Vite 8, you can undo the dependencies changes in package.json and update to Vite 8.
{
"dependencies": {
"vite": "npm:rolldown-vite@7.2.2"
"vite": "^8.0.0"
}
}Dependency Optimizer now uses Rolldown
Rolldown is now used for dependency optimization instead of esbuild. Vite still supports the optimizeDeps.esbuildOptions option for backward compatibility by converting it to optimizeDeps.rolldownOptions internally. But optimizeDeps.esbuildOptions is deprecated and will be removed in the future and we encourage you to migrate to optimizeDeps.rolldownOptions.
The following options are converted:
esbuildOptions.minify->rolldownOptions.output.minifyesbuildOptions.treeShaking->rolldownOptions.treeshakeesbuildOptions.define->rolldownOptions.transform.defineesbuildOptions.loader->rolldownOptions.moduleTypesesbuildOptions.preserveSymlinks->!rolldownOptions.resolve.symlinksesbuildOptions.resolveExtensions->rolldownOptions.resolve.extensionsesbuildOptions.mainFields->rolldownOptions.resolve.mainFieldsesbuildOptions.conditions->rolldownOptions.resolve.conditionNamesesbuildOptions.keepNames->rolldownOptions.output.keepNamesesbuildOptions.platform->rolldownOptions.platformesbuildOptions.plugins->rolldownOptions.plugins(partial support)
You can also get the options set by the compatibility layer from the configResolved hook:
const plugin = {
name: 'log-config',
configResolved(config) {
console.log('options', config.optimizeDeps.esbuildOptions)
},
},JS Transformation by Oxc
Oxc is now used for JS transformation instead of esbuild. Vite still supports the esbuild option for backward compatibility by converting it to oxc internally. But esbuild is deprecated and will be removed in the future and we encourage you to migrate to oxc.
The following options are converted:
esbuild.jsxInject->oxc.jsxInjectesbuild.include->oxc.includeesbuild.exclude->oxc.excludeesbuild.jsx->oxc.jsxesbuild.jsx: 'preserve'->oxc.jsx: 'preserve'esbuild.jsx: 'automatic'->oxc.jsx: { runtime: 'automatic' }esbuild.jsxImportSource->oxc.jsx.importSource
esbuild.jsx: 'transform'->oxc.jsx: { runtime: 'classic' }esbuild.jsxFactory->oxc.jsx.pragmaesbuild.jsxFragment->oxc.jsx.pragmaFrag
esbuild.jsxDev->oxc.jsx.developmentesbuild.jsxSideEffects->oxc.jsx.pure
esbuild.define->oxc.defineesbuild.banner-> custom plugin using transform hookesbuild.footer-> custom plugin using transform hook
esbuild.supported option is not supported by Oxc. If you need these options, please check oxc-project/oxc#15373.
You can also get the options set by the compatibility layer from the configResolved hook:
const plugin = {
name: 'log-config',
configResolved(config) {
console.log('options', config.oxc)
},
},Currently, Oxc transformer does not support lowering native decorators (oxc-project/oxc#9170).
Workaround for lowering native decorators
You can use Babel or SWC to lower native decorators for the time being. While SWC is faster than Babel, it does not support the latest decorator spec that esbuild supports.
The decorator spec has been updated multiple times since it reached stage 3 and the versions supported by each tools are (the version names are same with babel's options):
"2023-11"(esbuild and TS5.4+ and babel supports this version)"2023-05"(TS5.2+ supports this version)"2023-01"(TS5.0+ supports this version)"2022-03"(SWC supports this version)
If you want to use babel:
$ npm install -D @rollup/plugin-babel @babel/plugin-proposal-decorators$ yarn add -D @rollup/plugin-babel @babel/plugin-proposal-decorators$ pnpm add -D @rollup/plugin-babel @babel/plugin-proposal-decorators$ bun add -D @rollup/plugin-babel @babel/plugin-proposal-decorators$ deno add -D npm:@rollup/plugin-babel npm:@babel/plugin-proposal-decoratorsimport { defineConfig, withFilter } from 'vite'
import { babel } from '@rollup/plugin-babel'
export default defineConfig({
plugins: [
withFilter(
babel({
configFile: false,
plugins: [
['@babel/plugin-proposal-decorators', { version: '2023-11' }],
],
}),
// only run this transform if the file contains a decorator
{ transform: { code: '@' } },
),
],
})If you want to use SWC:
$ npm install -D @rollup/plugin-swc @swc/core$ yarn add -D @rollup/plugin-swc @swc/core$ pnpm add -D @rollup/plugin-swc @swc/core$ bun add -D @rollup/plugin-swc @swc/core$ deno add -D npm:@rollup/plugin-swc npm:@swc/coreimport { defineConfig, withFilter } from 'vite'
export default defineConfig({
// ...
plugins: [
withFilter(
swc({
swc: {
jsc: {
parser: { decorators: true, decoratorsBeforeExport: true },
// NOTE: SWC doesn't support '2023-11' version yet
transform: { decoratorVersion: '2022-03' },
},
},
}),
// only run this transform if the file contains a decorator
{ transform: { code: '@' } },
),
],
})Note that if you use a plugin that uses transformWithEsbuild function, you need to install esbuild as a dev dependency as it's now an optional dependency. transformWithEsbuild function is now deprecated and will be removed in the future. We recommend to use the new transformWithOxc function instead.
JS Minification by Oxc
Oxc Minifier is now used for JS minification by default instead of esbuild. You can use build.minify: 'esbuild' option to switch back to esbuild, but this is deprecated and will be removed in the future. Note that you need to install esbuild as a dev dependency as it's now an optional dependency.
If you were using esbuild.minify* options to control the minification behavior, you can use build.rolldownOptions.output.minify option instead. If you were using esbuild.drop option, you can use build.rolldownOptions.output.minify.compress.drop* options instead.
Property mangling feature is not supported by Oxc and the related options (mangleProps, reserveProps, mangleQuoted, mangleCache) are not supported. If you need these options, please check oxc-project/oxc#15375.
Note that esbuild and Oxc Minifier have a slightly different assumptions about the input code. While this would not affect most projects, you can compare the assumptions if the minifier breaks your code (esbuild assumptions, Oxc Minifier assumptions).
CSS Minification by Lightning CSS
Lightning CSS is now used for CSS minification by default. You can use build.cssMinify: 'esbuild' option to switch back to esbuild. Note that you need to install esbuild as a dev dependency as it's now an optional dependency.
Lightning CSS supports more syntax lowering, so you may see a bigger CSS bundle size.
Consistent CJS Interop
The default import from a CJS module is now handled in a consistent way.
If it matches one of the following conditions, the default import is the module.exports value of the importee CJS module. Otherwise, the default import is the module.exports.default value of the importee CJS module.
- The importer is
.mjsor.mts - The closest
package.jsonfor the importer has atypefield set tomodule - The
module.exports.__esModulevalue of the importee CJS module is not set to true
The previous behaviors
In dev, if it matches one of the following conditions, the default import is the module.exports value of the importee CJS module. Otherwise, the default import is the module.exports.default value of the importee CJS module.
- The importer is included in the dependency optimization and
.mjsor.mts - The importer is included in the dependency optimization and the closest
package.jsonfor the importer has atypefield set tomodule - The
module.exports.__esModulevalue of the importee CJS module is not set to true
In build, the conditions were:
- The
module.exports.__esModulevalue of the importee CJS module is not set to true defaultproperty ofmodule.exportsdoes not exist
(assuming build.commonjsOptions.defaultIsModuleExports is not changed from the default 'auto')
See Rolldown's document about this problem for more details: Ambiguous default import from CJS modules - Bundling CJS | Rolldown.
This change may break some existing code importing CJS modules. You can use the legacy.inconsistentCjsInterop: true option to temporary restore the previous behavior. Note that this option will be removed in the future. If you find a package that is affected by this change, please report it to the package author. Make sure to link to the Rolldown document above so that the author can understand the context.
Module Type Support and Auto Detection
This change only affects plugin authors.
Rolldown has an experimental Module type support, which is similar to esbuild's loader option. Due to this, Rolldown automatically sets a module type based on the extension of the resolved id.
If you are converting the content to JavaScript from other types in load or transform hooks, you may need to add moduleType: 'js' to the returned value.
const plugin = {
name: 'txt-loader',
load(id) {
if (id.endsWith('.txt')) {
const content = fs.readFile(id, 'utf-8')
return {
code: `export default ${JSON.stringify(content)}`,
moduleType: 'js',
}
}
},
}Removed Module Resolution Using Format Sniffing
When both browser and module fields are present in package.json, Vite used to resolve the field based on the content of the file, trying to pick the ESM file for browsers. This was introduced because some packages were using the module field to point to ESM files for Node.js and some other packages were using the browser field to point to UMD files for browsers. Given that the modern exports field solved this problem and is now adopted by many packages, Vite no longer uses this heuristic and always respects the order of the resolve.mainFields option. If you were relying on this behavior, you can use the resolve.alias option to map the field to the desired file or apply a patch with your package manager (e.g. patch-package, pnpm patch).
Require Calls For Externalized Modules
require calls for externalized modules are now preserved as require calls and not converted to import statements. This is to preserve the semantics of require calls.
If you want to convert them to import statements, you can use Rolldown's built-in esmExternalRequirePlugin, which is re-exported from vite.
import { defineConfig, esmExternalRequirePlugin } from 'vite'
export default defineConfig({
// ...
plugins: [
esmExternalRequirePlugin({
external: ['react', 'vue', /^node:/],
}),
],
})See Rolldown's document for more details: require external modules - Bundling CJS | Rolldown.
import.meta.url in UMD / IIFE
import.meta.url is not polyfilled in UMD / IIFE output formats. It will be replaced with undefined by default. If you prefer the previous behavior, you can use the define option with build.rolldownOptions.output.intro option. See Rolldown's document for more details: Well-known import.meta properties - Non ESM Output Formats | Rolldown.
Removed build.rollupOptions.watch.chokidar option
build.rollupOptions.watch.chokidar option is removed. Please migrate to build.rolldownOptions.watch.notify option.
Deprecate build.rollupOptions.output.manualChunks
output.manualChunks option is deprecated. Rolldown has advacedChunks option, which is more flexible. Please migrate to output.advancedChunks option. See Rolldown's document for more details about advancedChunks: Advanced Chunks - Rolldown.
Other Related Deprecations
The following options are deprecated and will be removed in the future:
build.rollupOptions: renamed tobuild.rolldownOptionsworker.rollupOptions: renamed toworker.rolldownOptionsbuild.commonjsOptions: it is now no-op
General Changes
Removed deprecated features
TODO: This change is not implemented yet, but will be implemented before stable release.
Advanced
There are other breaking changes which only affect few users.
- [TODO: this will be fixed before stable release] https://github.com/rolldown/rolldown/issues/5726 (affects nuxt, qwik)
- [TODO: this will be fixed before stable release] https://github.com/rolldown/rolldown/issues/3403 (affects sveltekit)
- [TODO: this will be fixed before stable release] Legacy chunks are emitted as an asset file instead of a chunk file due to the lack of prebuilt chunk emit feature (rolldown#4304). This means the chunk related options does not apply to legacy chunks and the manifest file will not include legacy chunks as a chunk file.
- [TODO: this will be fixed before stable release] resolver cache breaks minor cases in Vitest (rolldown-vite#466, vitest#8754)
- [TODO: this will be fixed before stable release] The resolver does not work with yarn pnp (rolldown-vite#324, rolldown-vite#392)
- [TODO: this will be fixed before stable release] native plugin ordering issue (rolldown-vite#373)
- [TODO: this will be fixed before stable release]
@vite-ignorecomment edge case (rolldown-vite#426) - [TODO: this will be fixed before stable release] https://github.com/rolldown/rolldown/issues/3403
- Extglobs are not supported yet (rolldown-vite#365)
definedoes not share reference for objects: When you pass an object as a value todefine, each variable will have a separate copy of the object. See Oxc Transformer document for more details.bundleobject changes (bundleis an object passed ingenerateBundle/writeBundlehooks, returned bybuildfunction):- Assigning to
bundle[foo]is not supported. This is discouraged by Rollup as well. Please usethis.emitFile()instead. - the reference is not shared across the hooks (rolldown-vite#410)
structuredClone(bundle)errors withDataCloneError: #<Object> could not be cloned. This is not supported anymore. Please clone it withstructuredClone({ ...bundle }). (rolldown-vite#128)
- Assigning to
- All parallel hooks in Rollup works as sequential hooks. See Rolldown's documentation for more details.
"use strict";is not injected sometimes. See Rolldown's documentation for more details.- Transforming to lower than ES5 with plugin-legacy is not supported (rolldown-vite#452)
- Passing the same browser with multiple versions of it to
build.targetoption now errors: esbuild selects the latest version of it, which was probably not what you intended. - Missing support by Rolldown: The following features are not supported by Rolldown and is no longer supported by Vite.
build.rollupOptions.output.format: 'system'(rolldown#2387)build.rollupOptions.output.format: 'amd'(rolldown#2387)- Complete support for TypeScript legacy namespace (oxc-project/oxc#14227)
shouldTransformCachedModulehook (rolldown#4389)resolveImportMetahook (rolldown#1010)renderDynamicImporthook (rolldown#4532)resolveFileUrlhook
parseAst/parseAstAsyncfunctions are now deprecated in favor ofparse/parseAsyncfunctions which has more features.
Migration from v6
Check the Migration from v6 Guide in the Vite v7 docs first to see the needed changes to port your app to Vite 7, and then proceed with the changes on this page.