Vite 8 + Rolldown: How a Dual-Bundler Integration Cut Production Build Times by 87%
(Vite 8 Rolldown migration | build speed)
When I first heard that a 46-second build had dropped to 6 seconds, I was honestly skeptical. Benchmark numbers always look better than reality. But then the same results started showing up in real production codebases at companies like Linear, GitLab, and Ramp. Linear's publicly documented case shows their 19,000-module codebase going from 46 seconds down to 6. Vite 8, officially released in March 2026, is not a simple version bump. It fundamentally changed the structure of the build pipeline, and those changes are showing up clearly in the numbers.
This article is primarily written for frontend developers already using Vite. If you're interested in build speed, you'll find the concepts section worth reading too. It's especially helpful if you're considering a migration or feeling the cost of CI build times.
Core Concepts
The Dual-Bundler Architecture: What Was the Problem?
Here's a simplified picture of how Vite 7 and earlier worked:
Dev server → esbuild (dependency pre-bundling) + Vite's own ESM server
Production build → RollupDuring development, esbuild pre-bundled node_modules, while Rollup handled production builds. Because the two tools behaved differently, situations would arise where "everything worked in dev but broke on build." I ran into this myself a few times in production — tracing the cause almost always led back to differences in how esbuild and Rollup handled tree-shaking.
Vite 8 consolidates both roles into a single tool: Rolldown. This fixes not just speed but also the long-standing structural weakness of dev/prod bundler inconsistency.
What Is Rolldown?
Rolldown is a JavaScript/TypeScript bundler written in Rust, developed by VoidZero — the company founded by Evan You, creator of Vue.js. It maintains a Rollup-compatible plugin API while delivering native Rust-level speed.
Looking at the internal pipeline, the entire process from parsing → transpiling → code optimization is handled by Oxc. Oxc is not just a compiler — it's a Rust-based toolkit that bundles a parser, linter, transpiler, and minifier into one. CSS minification has been switched from esbuild to Lightning CSS (also Rust).
Rolldown Internal Pipeline
──────────────────────────────────────
Source code input
└─▶ Oxc parser (AST generation)
└─▶ Oxc transpiler (TS/JSX → JS)
└─▶ Rolldown linker (chunk splitting · tree shaking)
└─▶ Oxc minifier
└─▶ Lightning CSS (CSS processing)
└─▶ Final bundle output
──────────────────────────────────────What matters here is that the VoidZero team builds both Rolldown and Oxc directly, and many core Vite contributors are VoidZero employees. Previously, esbuild, Rollup, and Babel were each maintained by separate teams, and that fragmentation was a barrier to integration and optimization. Vite 8 is the most visible result of this vertically integrated toolchain strategy.
How Much Faster Is It?
| Bundler | Build Time | Notes |
|---|---|---|
| Rolldown | 1.61s | Official benchmark, 19,000 modules |
| Rollup | 40.10s | Same conditions |
| Improvement | ~25× |
Real-world enterprise measurements show similar trends.
| Company | Before | After | Improvement |
|---|---|---|---|
| Linear | 46s | 6s | 87% faster |
| GitLab | 2m 30s | 22s | ~85% faster |
| Ramp | — | — | 57% faster |
| Beehiiv | — | — | 64% faster |
Measurement conditions vary across these numbers, so direct comparison is difficult — but the common thread is clear: the larger the codebase, the more dramatic the gains.
Practical Application
Example 1: Validate Rolldown First While Still on Vite 7
If jumping straight to Vite 8 feels risky, you can test Rolldown in isolation using the rolldown-vite package — keeping your existing Vite 7 config while just swapping the bundler. This is much easier when it comes to separating bundler issues from Vite API changes. I skipped this step myself at first and ended up tangling plugin issues with bundler issues, which cost me a lot of time.
The simplest approach is to alias vite to rolldown-vite.
# Simplest approach: install as alias
pnpm add vite@npm:rolldown-viteIf you want more explicit control, you can use pnpm.overrides.
pnpm remove vite
pnpm add -D rolldown-vite// package.json
{
"devDependencies": {
"rolldown-vite": "^8.0.0"
},
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@*"
}
}
}Running pnpm build in this state will use Rolldown as the bundler while keeping your Vite 7 config intact. If the build output and runtime look fine, the next step is to upgrade to Vite 8.
Example 2: Upgrading to Vite 8 Proper
Once Rolldown is validated, upgrading to Vite 8 itself is simpler than you might expect.
pnpm add -D vite@^8.0.0Among the major changes, the most hands-on work involves config key renames.
// vite.config.ts — Vite 7
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
})// vite.config.ts — Vite 8
export default defineConfig({
build: {
rolldownOptions: { // ← renamed from rollupOptions
output: {
advancedChunks: { // ← more flexible pattern-based matching than manualChunks
groups: [
{ name: 'vendor', test: /node_modules/ },
{ name: 'ui', test: /src\/components/ },
],
},
},
},
},
})advancedChunks offers more flexible pattern-based matching than manualChunks. Projects managing hundreds of chunks will also see a reduction in the config code itself.
| Change | Vite 7 | Vite 8 | Notes |
|---|---|---|---|
| Bundler | esbuild + Rollup | Rolldown | Automatic |
| CSS minification | esbuild | Lightning CSS | Can be explicitly overridden |
| Chunk config key | rollupOptions |
rolldownOptions |
Auto-conversion supported |
import.meta.hot.accept |
URL passable | Must change to id | Manual update required |
The thing I paid the most attention to during migration was CSS minification output changes. Lightning CSS and esbuild can produce subtly different CSS output, so if you want to preserve the existing behavior, you can configure it explicitly like this:
// vite.config.ts — Keep esbuild CSS minification instead of Lightning CSS
export default defineConfig({
css: {
transformer: 'postcss', // Disable Lightning CSS
},
build: {
cssMinify: 'esbuild',
},
})Example 3: Full Bundle Mode — Eliminating Dev/Prod Inconsistency at the Root
One of the new capabilities unlocked by the Rolldown integration is Full Bundle Mode. It makes the dev server use Rolldown to generate bundles as well, which structurally eliminates inconsistencies between dev and prod output.
// vite.config.ts — Enable Full Bundle Mode
export default defineConfig({
dev: {
bundleMode: 'bundle', // Default: 'module' (the existing ESM approach)
},
})According to official announcements, this significantly reduces network requests compared to the traditional ESM approach. In monorepos with thousands of modules, initial page load on the dev server feels noticeably faster.
That said, a few behavioral changes are worth knowing about upfront. The HMR update mechanism differs from individual ESM module replacement, and there's a slight increase in initial build overhead when the first bundle is generated. This mode suits teams that want maximum alignment between dev and prod output; teams that prioritize fast HMR feedback loops may be perfectly fine staying on the default (module) mode.
Pros and Cons
Advantages
| Item | Details |
|---|---|
| Build speed | ~25× faster than Rollup per official benchmark (19,000 modules); 87% reduction based on Linear's case (46s → 6s) |
| Bundler consistency | Same bundler in dev/prod → structural elimination of build inconsistency bugs |
| Plugin compatibility | Near-full compatibility with Rollup/Vite plugin API; minimal ecosystem disruption |
| HMR improvements | 3× faster dev server startup for large projects; 40% reduction in full reloads |
| New features | Module Federation, module-level persistent cache, flexible chunk splitting (advancedChunks) |
Downsides and Caveats
| Item | Details | Mitigation |
|---|---|---|
| API key renames | rollupOptions → rolldownOptions |
Auto-converted initially, update manually long-term |
| No extglob pattern support | Existing glob extension patterns in rollupOptions may silently fail in Rolldown |
Replace with standard regex patterns |
| TypeScript legacy namespaces | Older enterprise codebases or Angular legacy code using namespace syntax extensively may be partially affected |
Check release notes and apply workarounds |
import.meta.hot.accept |
URL passing no longer works; must switch to id-based approach | Replace with id-based approach |
| CSS minification changes | Switching to Lightning CSS as default may produce subtly different output | Configure explicitly to preserve existing behavior |
| Small projects | If builds already finish in seconds, the perceived benefit is limited | Focus on the dev/prod consistency benefit over speed |
Lightning CSS: A Rust-based CSS parser/transformer/minifier developed by Mozilla with contributions from the Parcel team. It handles autoprefixing, CSS Modules, and downleveling of modern CSS syntax in a single tool.
Module Federation: A micro-frontend technique where multiple independently-built apps share each other's modules at runtime. It gained prominence with Webpack 5 and was added as official support in Rolldown 1.0 stable.
The Most Common Mistakes in Practice
I skipped the isolation step the first time and wasted two days untangling plugin issues from bundler issues. Based on that experience, here are three pitfalls I commonly see:
- Skipping the
rolldown-viteintermediate step and going straight to Vite 8 — When bundler issues and Vite API change issues mix together, root-cause analysis gets very hard. The isolation step pays off more the larger your project is or the more plugins you have. - Deploying without verifying CSS minification output — Lightning CSS and esbuild can produce subtly different CSS. It's worth visually checking the styles on key pages after
pnpm build. - Carrying extglob patterns straight into
rolldownOptions— If you had glob extension patterns in yourrollupOptions, review the pattern list before migrating. Unsupported patterns may be silently ignored without any error.
Closing Thoughts
Your next PR could give back dozens of seconds in the CI pipeline. The real significance of Vite 8 + Rolldown isn't the speed numbers themselves — it's that it simultaneously eliminates the dual-bundler inconsistency that has been a structural weakness in Vite for years, while achieving dramatic performance gains at the same time.
Here are 3 steps you can start with right now:
- Isolated Rolldown test: In your existing project, run
pnpm add vite@npm:rolldown-viteto swap just the bundler, then runpnpm build. You can keep your Vite 7 config intact and compare build output and speed first. - Upgrade to Vite 8: If the isolated test looks clean, run
pnpm add -D vite@^8.0.0to upgrade, then audit yourrollupOptions→rolldownOptionskey changes and anyimport.meta.hot.acceptcalls. - Compare build times before and after: Record your build time from the CI pipeline logs ahead of time, then compare after the upgrade. Medium-to-large projects will see a noticeable difference.
References
- Vite 8.0 is out! | vite.dev
- Vite 8 Beta: The Rolldown-powered Vite | vite.dev
- Vite 8.1 is out! | vite.dev
- Migration from v7 | vite.dev
- Announcing Rolldown 1.0 | voidzero.dev
- Announcing Rolldown-Vite | voidzero.dev
- Introduction | rolldown.rs
- Vite team claims 10-30x faster builds with Rolldown | The Register
- Vite Version 8: Unified Rust-Based Bundler and Up to 30x Faster Builds | InfoQ
- Testing out Vite 8 on SPA: Vite 8 is 5x faster | Peterbe.com
- Rust Is Eating the JavaScript Toolchain | DEV Community
- rolldown/rolldown | GitHub
- vitejs/rolldown-vite | GitHub