Skip to content

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.

json
{
  "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:

You can also get the options set by the compatibility layer from the configResolved hook:

js
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.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:

js
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:

bash
$ npm install -D @rollup/plugin-babel @babel/plugin-proposal-decorators
bash
$ yarn add -D @rollup/plugin-babel @babel/plugin-proposal-decorators
bash
$ pnpm add -D @rollup/plugin-babel @babel/plugin-proposal-decorators
bash
$ bun add -D @rollup/plugin-babel @babel/plugin-proposal-decorators
bash
$ deno add -D npm:@rollup/plugin-babel npm:@babel/plugin-proposal-decorators
vite.config.ts
ts
import { 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:

bash
$ npm install -D @rollup/plugin-swc @swc/core
bash
$ yarn add -D @rollup/plugin-swc @swc/core
bash
$ pnpm add -D @rollup/plugin-swc @swc/core
bash
$ bun add -D @rollup/plugin-swc @swc/core
bash
$ deno add -D npm:@rollup/plugin-swc npm:@swc/core
js
import { 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 .mjs or .mts
  • The closest package.json for the importer has a type field set to module
  • The module.exports.__esModule value 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 .mjs or .mts
  • The importer is included in the dependency optimization and the closest package.json for the importer has a type field set to module
  • The module.exports.__esModule value of the importee CJS module is not set to true

In build, the conditions were:

  • The module.exports.__esModule value of the importee CJS module is not set to true
  • default property of module.exports does 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.

js
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.

js
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.

The following options are deprecated and will be removed in the future:

  • build.rollupOptions: renamed to build.rolldownOptions
  • worker.rollupOptions: renamed to worker.rolldownOptions
  • build.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-ignore comment 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)
  • define does not share reference for objects: When you pass an object as a value to define, each variable will have a separate copy of the object. See Oxc Transformer document for more details.
  • bundle object changes (bundle is an object passed in generateBundle / writeBundle hooks, returned by build function):
    • Assigning to bundle[foo] is not supported. This is discouraged by Rollup as well. Please use this.emitFile() instead.
    • the reference is not shared across the hooks (rolldown-vite#410)
    • structuredClone(bundle) errors with DataCloneError: #<Object> could not be cloned. This is not supported anymore. Please clone it with structuredClone({ ...bundle }). (rolldown-vite#128)
  • 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.target option 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.
  • parseAst / parseAstAsync functions are now deprecated in favor of parse / parseAsync functions 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.

Released under the MIT License. (d9cde6b8)