869 words
4 minutes

Vite 8 manualChunks: Migrate Rollup Splits to Rolldown codeSplitting

2026-08-08
2026-09-04
Frontend
Vite
/
Frontend
/
JavaScript
/
Migration

Vite 8 changes the bundler underneath the build from the older Rollup-oriented path to Rolldown. If your vite.config contains build.rollupOptions.output.manualChunks, migrate that split instead of assuming the old object syntax will keep working: Vite 8 no longer supports the object form, and the function form is deprecated.

The replacement is build.rolldownOptions.output.codeSplitting with explicit groups:

import { defineConfig } from 'vite';
export default defineConfig({
build: {
rolldownOptions: {
output: {
codeSplitting: {
groups: [
{
test: /node_modules\/(react|react-dom)/,
name: 'framework',
},
],
},
},
},
},
});

The regex and chunk name are examples. Choose groups from the dependencies and loading behavior of your application, then verify the generated output rather than treating every old manualChunks map as a mechanical rename.

Map the old and new configuration boundaries#

An older Vite configuration may look like this:

export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
});

In Vite 8, move the underlying bundler options and express the split as a codeSplitting.groups rule:

export default defineConfig({
build: {
rolldownOptions: {
output: {
codeSplitting: {
groups: [
{
test: /node_modules\//,
name: 'vendor',
},
],
},
},
},
},
});

The migration guide also lists build.rollupOptions as deprecated in favor of build.rolldownOptions. Update the outer option at the same time so a later Vite upgrade does not leave the old compatibility name scattered through the config.

Do not blindly split every dependency#

Rolldown’s manual code-splitting documentation warns that moving modules between chunks can change execution behavior. A broad node_modules group is easy to write, but it can create a large vendor chunk, capture dependencies recursively, or alter the order in which modules initialize.

Use a staged migration:

  1. Record the old build’s chunk names and the routes that load them.
  2. Replace one manualChunks rule with one narrow codeSplitting group.
  3. Run the production build and inspect dist/assets.
  4. Load the initial route and every route that uses a dynamic import.
  5. Check side effects, circular imports, and cache headers before adding another group.

Rolldown may also emit a runtime chunk when manual splitting needs a stable execution order. That is not automatically a regression. The question is whether the resulting application loads and initializes correctly under the deployment’s asset and cache rules.

Check for a silently lost lazy boundary#

A successful build does not prove that a lazy boundary survived. An upstream Vite issue report for Vite 8.2.0 describes the function form of manualChunks being called while its assignments were silently discarded. In that reproduction, a shared CommonJS module returned to a lazy chunk, the entry still imported it statically, and the generated HTML preloaded the supposedly lazy chunk without a warning. The report measured the boot bundle growing from 978 KB to 1,085 KB gzip and all 275 assignments being ignored.

This is a bounded compatibility-path report, not proof that every Vite 8 project has the same failure. Verify the output that your application actually ships:

Terminal window
pnpm vite build
find dist/assets -maxdepth 1 -type f | sort
rg -n 'modulepreload' dist/index.html

Compare the generated entry imports and modulepreload links with the route’s dynamic import. Use this decision table:

Output checkInterpretationNext move
The expected lazy route points to its own chunk and the entry does not preload itThe lazy boundary is presentLoad the route in a fresh profile and check its request waterfall
The entry imports or index.html preloads a chunk that should be lazyThe boundary may have been lostReplace the compatibility manualChunks rule with native codeSplitting.groups, then inspect shared CommonJS and static imports
Chunk names changed but the expected lazy import remains lazyThe layout changed without proving a regressionCompare initial bytes, lazy-route bytes, cache headers, and initialization order

Verify the build instead of the config alone#

Run the same build command used by CI, then inspect both the build output and the application behavior:

Terminal window
pnpm vite build
find dist/assets -maxdepth 1 -type f | sort

For a package script, use pnpm build instead. Check the generated HTML for the expected entry assets and modulepreload links, open a page that loads a lazy chunk, and test a fresh browser profile so a previously cached chunk does not hide a broken import.

If the project still targets an older Vite release, do not copy the Vite 8 configuration into it without checking that release’s supported options. Keep the migration in the same change as the Vite upgrade, or guard the configuration in a way the project can test in both environments.

FAQ#

Q: Is manualChunks removed in Vite 8?#

A: The object form of build.rollupOptions.output.manualChunks is no longer supported, and the function form is deprecated. Vite directs users to Rolldown’s codeSplitting option; an upstream Vite 8.2.0 report also shows why a successful compatibility-path build is not enough.

Q: How can I tell that Vite lost a lazy split?#

A: Inspect the entry imports and modulepreload links in dist/index.html after a clean production build. If a chunk expected only behind a dynamic import is on the boot path, switch to native codeSplitting.groups and repeat the output and route checks.

Q: What replaces build.rollupOptions?#

A: Use build.rolldownOptions for direct Rolldown configuration. Vite lists build.rollupOptions as a deprecated name during the Vite 8 migration.

Q: Will codeSplitting always improve performance?#

A: No. It changes chunk boundaries, not a guaranteed performance outcome. Test initial loading, lazy routes, caching, and module initialization with the actual application and deployment headers.

References:

Vite 8 migration guide

Vite production build guide

Rolldown manual code splitting

Vite issue: manualChunks assignments ignored in Vite 8.2.0 report

Vite 8 manualChunks: Migrate Rollup Splits to Rolldown codeSplitting
https://laplusda.com/en/posts/vite-8-manualchunks-rolldown/
Author
Zero
Published at
2026-08-08
License
CC BY-NC-SA 4.0
Was this article useful?

Report a typo or broken link, or suggest a related topic.