Skip to content

docs: migration guide for v7 #20051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ export default defineConfig({
link: '/guide/rolldown',
},
{
text: 'Migration from v5',
text: 'Migration from v6',
link: '/guide/migration',
},
{
Expand Down
173 changes: 36 additions & 137 deletions docs/guide/migration.md
Original file line number Diff line number Diff line change
@@ -1,154 +1,53 @@
# Migration from v5
# Migration from v6

## Environment API
## Node.js Support

As part of the new experimental [Environment API](/guide/api-environment.md), a big internal refactoring was needed. Vite 6 strives to avoid breaking changes to ensure most projects can quickly upgrade to the new major. We'll wait until a big portion of the ecosystem has moved to stabilize and start recommending the use of the new APIs. There may be some edge cases but these should only affect low level usage by frameworks and tools. We have worked with maintainers in the ecosystem to mitigate these differences before the release. Please [open an issue](https://github.com/vitejs/vite/issues/new?assignees=&labels=pending+triage&projects=&template=bug_report.yml) if you spot a regression.
Vite no longer supports Node.js 18, which reached its EOL. Node.js 20.19+ / 22.12+ is now required.
Copy link
Contributor

@ghiscoding ghiscoding May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing you guys decided to use Node.js 20.19+ because of the recent require(esm) feature? If so, it might be worth mentioning the reasoning somewhere in the migration since that is quite far from the regular v20.0 :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is the reason. I didn't include the reason here because I thought the focus should be on the necessary steps for the migration. Do you think it's important to explain the reason? Or would it be more helpful to highlight that this is not 20.0+ / 22.0+?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right, I do think it's useful to know, but it could indeed be mentioned somewhere else (perhaps in the official release blog post might be a better place to put it?). We're slowly getting closer to an ESM-Only world 🚀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have this is a draft for the blog post:

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 lets us distribute Vite as ESM only without preventing Vite JavaScript API from being required from 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.


Some internal APIs have been removed due to changes in Vite's implementation. If you were relying on one of them, please create a [feature request](https://github.com/vitejs/vite/issues/new?assignees=&labels=enhancement%3A+pending+triage&projects=&template=feature_request.yml).
## Default Browser Target change

## Vite Runtime API
The default browser value of `build.target` is updated to a newer browser.

The experimental Vite Runtime API evolved into the Module Runner API, released in Vite 6 as part of the new experimental [Environment API](/guide/api-environment). Given that the feature was experimental the removal of the previous API introduced in Vite 5.1 isn't a breaking change, but users will need to update their use to the Module Runner equivalent as part of migrating to Vite 6.
- Chrome 87 → 107
- Edge 88 → 107
- Firefox 78 → 104
- Safari 14.0 → 16.0

## General Changes

### Default value for `resolve.conditions`

This change does not affect users that did not configure [`resolve.conditions`](/config/shared-options#resolve-conditions) / [`ssr.resolve.conditions`](/config/ssr-options#ssr-resolve-conditions) / [`ssr.resolve.externalConditions`](/config/ssr-options#ssr-resolve-externalconditions).

In Vite 5, the default value for `resolve.conditions` was `[]` and some conditions were added internally. The default value for `ssr.resolve.conditions` was the value of `resolve.conditions`.

From Vite 6, some of the conditions are no longer added internally and need to be included in the config values.
The conditions that are no longer added internally for

- `resolve.conditions` are `['module', 'browser', 'development|production']`
- `ssr.resolve.conditions` are `['module', 'node', 'development|production']`

The default values for those options are updated to the corresponding values and `ssr.resolve.conditions` no longer uses `resolve.conditions` as the default value. Note that `development|production` is a special variable that is replaced with `production` or `development` depending on the value of `process.env.NODE_ENV`. These default values are exported from `vite` as `defaultClientConditions` and `defaultServerConditions`.

If you specified a custom value for `resolve.conditions` or `ssr.resolve.conditions`, you need to update it to include the new conditions.
For example, if you previously specified `['custom']` for `resolve.conditions`, you need to specify `['custom', ...defaultClientConditions]` instead.

### JSON stringify

In Vite 5, when [`json.stringify: true`](/config/shared-options#json-stringify) is set, [`json.namedExports`](/config/shared-options#json-namedexports) was disabled.

From Vite 6, even when `json.stringify: true` is set, `json.namedExports` is not disabled and the value is respected. If you wish to achieve the previous behavior, you can set `json.namedExports: false`.

Vite 6 also introduces a new default value for `json.stringify` which is `'auto'`, which will only stringify large JSON files. To disable this behavior, set `json.stringify: false`.

### Extended support of asset references in HTML elements
These browser versions align with [Baseline](https://web-platform-dx.github.io/web-features/) Widely Available feature sets as of 2025-05-01.
In other words, they were all released before 2022-11-01.

In Vite 5, only a few supported HTML elements were able to reference assets that will be processed and bundled by Vite, such as `<link href>`, `<img src>`, etc.
In Vite 5, the default target was named `'modules'`, but this is no longer available. Instead, a new default target `'baseline-widely-available'` is introduced.

Vite 6 extends the support to even more HTML elements. The full list can be found at the [HTML features](/guide/features.html#html) docs.

To opt-out of HTML processing on certain elements, you can add the `vite-ignore` attribute on the element.

### postcss-load-config

[`postcss-load-config`](https://npmjs.com/package/postcss-load-config) has been updated to v6 from v4. [`tsx`](https://www.npmjs.com/package/tsx) or [`jiti`](https://www.npmjs.com/package/jiti) is now required to load TypeScript postcss config files instead of [`ts-node`](https://www.npmjs.com/package/ts-node). Also [`yaml`](https://www.npmjs.com/package/yaml) is now required to load YAML postcss config files.

### Sass now uses modern API by default

In Vite 5, the legacy API was used by default for Sass. Vite 5.4 added support for the modern API.

From Vite 6, the modern API is used by default for Sass. If you wish to still use the legacy API, you can set [`css.preprocessorOptions.sass.api: 'legacy'` / `css.preprocessorOptions.scss.api: 'legacy'`](/config/shared-options#css-preprocessoroptions). But note that the legacy API support will be removed in Vite 7.

To migrate to the modern API, see [the Sass documentation](https://sass-lang.com/documentation/breaking-changes/legacy-js-api/).

### Customize CSS output file name in library mode

In Vite 5, the CSS output file name in library mode was always `style.css` and cannot be easily changed through the Vite config.
## General Changes

From Vite 6, the default file name now uses `"name"` in `package.json` similar to the JS output files. If [`build.lib.fileName`](/config/build-options.md#build-lib) is set with a string, the value will also be used for the CSS output file name. To explicitly set a different CSS file name, you can use the new [`build.lib.cssFileName`](/config/build-options.md#build-lib) to configure it.
### Removed Sass legacy API support

To migrate, if you had relied on the `style.css` file name, you should update references to it to the new name based on your package name. For example:
As planned, support for the Sass legacy API is removed. Vite now only supports the modern API.

```json [package.json]
{
"name": "my-lib",
"exports": {
"./style.css": "./dist/style.css" // [!code --]
"./style.css": "./dist/my-lib.css" // [!code ++]
}
}
```
## Removed deprecated features

If you prefer to stick with `style.css` like in Vite 5, you can set `build.lib.cssFileName: 'style'` instead.
- `splitVendorChunkPlugin` (deprecated in v5.2.7)
- This plugin was originally provided to ease migration to Vite v2.9.
- The `build.rollupOptions.output.manualChunks` option can be used to control the chunking behavior if needed.
- Hook-level `enforce` / `transform` for `transformIndexHtml` (deprecated in v4.0.0)
- It was changed to align the interface with [Rollup's object hooks](https://rollupjs.org/plugin-development/#build-hooks:~:text=Instead%20of%20a%20function%2C%20hooks%20can%20also%20be%20objects.).
- `order` should be used instead of `enforce`, and `handler` should be used instead of `transform`.

## Advanced

There are other breaking changes which only affect few users.

- [[#17922] fix(css)!: remove default import in ssr dev](https://github.com/vitejs/vite/pull/17922)
- Support for default import of CSS files was [deprecated in Vite 4](https://v4.vite.dev/guide/migration.html#importing-css-as-a-string) and removed in Vite 5, but it was still unintentionally supported in SSR dev mode. This support is now removed.
- [[#15637] fix!: default `build.cssMinify` to `'esbuild'` for SSR](https://github.com/vitejs/vite/pull/15637)
- [`build.cssMinify`](/config/build-options#build-cssminify) is now enabled by default even for SSR builds.
- [[#18070] feat!: proxy bypass with WebSocket](https://github.com/vitejs/vite/pull/18070)
- `server.proxy[path].bypass` is now called for WebSocket upgrade requests and in that case, the `res` parameter will be `undefined`.
- [[#18209] refactor!: bump minimal terser version to 5.16.0](https://github.com/vitejs/vite/pull/18209)
- Minimal supported terser version for [`build.minify: 'terser'`](/config/build-options#build-minify) was bumped to 5.16.0 from 5.4.0.
- [[#18231] chore(deps): update dependency @rollup/plugin-commonjs to v28](https://github.com/vitejs/vite/pull/18231)
- [`commonjsOptions.strictRequires`](https://github.com/rollup/plugins/blob/master/packages/commonjs/README.md#strictrequires) is now `true` by default (was `'auto'` before).
- This may lead to larger bundle sizes but will result in more deterministic builds.
- If you are specifying a CommonJS file as an entry point, you may need additional steps. Read [the commonjs plugin documentation](https://github.com/rollup/plugins/blob/master/packages/commonjs/README.md#using-commonjs-files-as-entry-points) for more details.
- [[#18243] chore(deps)!: migrate `fast-glob` to `tinyglobby`](https://github.com/vitejs/vite/pull/18243)
- Range braces (`{01..03}``['01', '02', '03']`) and incremental braces (`{2..8..2}``['2', '4', '6', '8']`) are no longer supported in globs.
- [[#18395] feat(resolve)!: allow removing conditions](https://github.com/vitejs/vite/pull/18395)
- This PR not only introduces a breaking change mentioned above as "Default value for `resolve.conditions`", but also makes `resolve.mainFields` to not be used for no-externalized dependencies in SSR. If you were using `resolve.mainFields` and want to apply that to no-externalized dependencies in SSR, you can use [`ssr.resolve.mainFields`](/config/ssr-options#ssr-resolve-mainfields).
- [[#18493] refactor!: remove fs.cachedChecks option](https://github.com/vitejs/vite/pull/18493)
- This opt-in optimization was removed due to edge cases when writing a file in a cached folder and immediately importing it.
- ~~[[#18697] fix(deps)!: update dependency dotenv-expand to v12](https://github.com/vitejs/vite/pull/18697)~~
- ~~Variables used in interpolation should be declared before the interpolation now. For more details, see [the `dotenv-expand` changelog](https://github.com/motdotla/dotenv-expand/blob/v12.0.1/CHANGELOG.md#1200-2024-11-16).~~ This breaking change was reverted in v6.1.0.
- [[#16471] feat: v6 - Environment API](https://github.com/vitejs/vite/pull/16471)

- Updates to an SSR-only module no longer triggers a full page reload in the client. To return to the previous behaviour, a custom Vite plugin can be used:
<details>
<summary>Click to expand example</summary>

```ts twoslash
import type { Plugin, EnvironmentModuleNode } from 'vite'

function hmrReload(): Plugin {
return {
name: 'hmr-reload',
enforce: 'post',
hotUpdate: {
order: 'post',
handler({ modules, server, timestamp }) {
if (this.environment.name !== 'ssr') return

let hasSsrOnlyModules = false

const invalidatedModules = new Set<EnvironmentModuleNode>()
for (const mod of modules) {
if (mod.id == null) continue
const clientModule =
server.environments.client.moduleGraph.getModuleById(mod.id)
if (clientModule != null) continue

this.environment.moduleGraph.invalidateModule(
mod,
invalidatedModules,
timestamp,
true,
)
hasSsrOnlyModules = true
}

if (hasSsrOnlyModules) {
server.ws.send({ type: 'full-reload' })
return []
}
},
},
}
}
```

</details>

## Migration from v4

Check the [Migration from v4 Guide](https://v5.vite.dev/guide/migration.html) in the Vite v5 docs first to see the needed changes to port your app to Vite 5, and then proceed with the changes on this page.
- [[#19979] chore: declare version range for peer dependencies](https://github.com/vitejs/vite/pull/19979)
- Specified the peer dependencies version range for CSS preprocessors.
- [[#20013] refactor: remove no-op `legacy.proxySsrExternalModules`](https://github.com/vitejs/vite/pull/20013)
- `legacy.proxySsrExternalModules` property had no effect since Vite 6. It is now removed.
- [[#19985] refactor!: remove deprecated no-op type only properties](https://github.com/vitejs/vite/pull/19985)
- The following unused properties are now removed: `ModuleRunnerOptions.root`, `ViteDevServer._importGlobMap`, `ResolvePluginOptions.isFromTsImporter`, `ResolvePluginOptions.getDepsOptimizer`, `ResolvePluginOptions.shouldExternalize`, `ResolvePluginOptions.ssrConfig`
- [[#19986] refactor: remove deprecated env api properties](https://github.com/vitejs/vite/pull/19986)
- These properties were deprecated from the beginning. It is now removed.
- [[#19987] refactor!: remove deprecated `HotBroadcaster` related types](https://github.com/vitejs/vite/pull/19987)
- These types were introduced as part of the now-deprecated Runtime API. It is now removed: `HMRBroadcaster`, `HMRBroadcasterClient`, `ServerHMRChannel`, `HMRChannel`

## Migration from v5

Check the [Migration from v5 Guide](https://v6.vite.dev/guide/migration.html) in the Vite v6 docs first to see the needed changes to port your app to Vite 6, and then proceed with the changes on this page.