September 2, 2026

What Breaks When You Upgrade to Vite 8 (and Rolldown)

Photo of Marco Orta Marco Orta | 10 min read
Compartir
A glossy lightning bolt in a yellow-to-violet gradient splitting along a jagged seam, with fragments drifting away
Table of Contents

    Vite 8 shipped stable on March 12, 2026, and it replaces both Rollup and esbuild with a single Rust bundler, Rolldown. Most of what breaks does so quietly: no red error, just different output. And here’s the part that catches people off guard — if you upgraded to Astro 7 any time after its June 2026 release, you got Vite 8 bundled underneath, whether you asked for it or not. This site runs Astro 7.2.2, and its node_modules/astro/package.json pins "vite": "^8.0.13". If you followed the Astro 7 migration, this post is the part nobody told you about.

    Where are you coming from?

    The list below applies differently depending on how you got here:

    • You run Vite directly and you’re on Vite 7. The straightforward case. Read the config renames and the CJS interop section, run a build, done.
    • You’re on Vite 6 or earlier. You’re jumping two majors’ worth of changes at once — the Vite 7 migration (Node 20.19+, ESM output) plus everything below. Do it in two steps: land on 7 first, verify, then go to 8.
    • You didn’t touch Vite. You upgraded Astro, Nuxt, SvelteKit, or another meta-framework, and Vite 8 came along. This is the group this post is really for. Nobody put “new bundler” in your changelog entry; it just showed up as a vite line in package-lock.json. Everything from here still applies to you — you just didn’t choose the timing.

    What actually changed, in one screen

    AreaVite 7Vite 8
    Production bundlerRollupRolldown (Rust)
    Dev-time dependency pre-bundlingesbuildRolldown
    JS transform / minifyesbuildOxc
    CSS minifyesbuildLightning CSS
    build.rollupOptionsvaliddeprecated, renamed build.rolldownOptions
    DistributionESMESM only (unchanged, just stricter)
    Node.js minimum20.19+ / 22.12+same
    Install sizebaseline+~15 MB (native binaries)
    Default build.targetChrome 107, Safari 16.0Chrome 111, Safari 16.4

    The headline number is real: Vite’s own announcement cites Linear’s production build dropping from 46s to 6s, Ramp at 57% faster, Beehiiv at 64%, Mercedes-Benz.io at 38%. Those are the upside. The rest of this post is the part that doesn’t make the release notes headline.

    Breaking changes, ordered by impact

    1. CommonJS default imports resolve differently — silently

    This is the one worth reading twice, because it produces no build error. Vite 8’s migration guide is explicit: the default import from a CJS module used to resolve inconsistently between dev and build; now it’s consistent, but the rule changed. The default import is the whole module.exports value only if one of these is true — the importer is .mjs/.mts, the importer’s closest package.json has "type": "module", or the CJS module’s __esModule flag isn’t true. Otherwise you get module.exports.default.

    In practice, this means a working import can start returning a wrapper object instead of the function you expect:

    // cjs-pkg ships: module.exports = { __esModule: true, default: function greet() {} }
    
    import greet from 'cjs-pkg';
    greet(); // Vite 7, dev: worked
              // Vite 8, plain .js without "type": "module": TypeError: greet is not a function
    

    The escape hatch is one line, and it buys you time to fix imports one by one instead of all at once:

    // vite.config.js
    export default defineConfig({
      legacy: { inconsistentCjsInterop: true }, // restores the old, inconsistent behavior
    });
    

    It’s marked deprecated on purpose — treat it as a bridge, not a destination. If a third-party package is the one tripping this, the docs ask you to report it to the package author with a link to Rolldown’s CJS interop explanation, not just patch around it forever.

    2. build.rollupOptions is now build.rolldownOptions

    This one at least fails loudly enough to notice — a deprecation warning on every build, not a crash yet, because a compatibility shim keeps the old key working:

    // Before (Vite 7)
    export default defineConfig({
      build: {
        rollupOptions: {
          input: { main: './src/main.ts' },
        },
      },
    });
    
    // After (Vite 8)
    export default defineConfig({
      build: {
        rolldownOptions: {
          input: { main: './src/main.ts' },
        },
      },
    });
    

    worker.rollupOptions gets the same treatment (worker.rolldownOptions). If you have both in a monorepo config that’s shared across packages, grep -rn "rollupOptions" . before you start finds every place at once.

    3. manualChunks as an object is gone, not deprecated — removed

    Buried inside the rename above is a sharper edge: the object form of output.manualChunks is not supported anymore, full stop. Only the function form still works, and it’s marked deprecated too, in favor of Rolldown’s own codeSplitting option.

    // Vite 7 — this pattern is common in real configs
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom'], // object form
          },
        },
      },
    },
    
    // Vite 8 — object form throws at build time; convert to a function, minimum viable fix
    build: {
      rolldownOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules/react')) return 'vendor';
          },
        },
      },
    },
    

    This is the one most likely to actually break your build (not just warn), because plenty of copy-pasted Vite configs use the object form for vendor splitting.

    4. build.commonjsOptions is now a no-op

    No warning, no error — it’s just ignored. If your config sets build.commonjsOptions.include, .exclude, or .requireReturnsDefault to work around a specific CJS package, that workaround silently stops applying after the upgrade. The symptom shows up downstream, in whatever the option used to fix, not at the config line itself — which makes it easy to blame the wrong thing.

    5. Node.js 20.19+ / 22.12+ is a hard floor, and it’s about require(esm)

    Same requirement as Vite 7, so if you’re coming from there this changes nothing. But if you’re jumping from Vite 6, this is new: Vite ships ESM-only, and those specific patch versions are the ones where Node supports require(esm) without a flag — the mechanism that lets a CJS-era toolchain still load an ESM-only package. Anything older fails to even install correctly, not just run oddly.

    6. Yarn PnP: no official verdict, but it’s not solid

    Vite’s own docs don’t carry a “Yarn PnP: unsupported” line, but the rolldown-vite issue tracker has multiple open reports of dependency resolution failing specifically under Yarn’s Plug’n’Play mode — packages that resolve fine with node_modules throwing Failed to resolve import under PnP. If your team runs Yarn Berry with nodeLinker: pnp, treat Vite 8 as “test in a branch before touching CI,” not as a safe drop-in yet.

    7. Install size grows by roughly 15 MB

    Confirmed in the release announcement: about 10 MB from Lightning CSS (now the default CSS minifier, no longer optional) and about 5 MB from Rolldown’s native binary. Nothing breaks functionally, but if you build Docker images with tight layer budgets or you’re vendoring node_modules into a Lambda bundle, this is a real line item to check — and it applies even if you never touch Vite directly, because it rides in as Astro’s (or Nuxt’s, or SvelteKit’s) dependency.

    8. Default browser targets moved up — and old browsers fail without a build warning

    build.target defaults jumped: Chrome 107→111, Edge 107→111, Firefox 104→114, Safari 16.0→16.4, aligned to Baseline Widely Available as of January 2026. Vite compiles happily either way — the failure, if you have one, shows up as broken JavaScript in an old Safari in someone’s production analytics, weeks later, with nothing in your build log pointing at the cause. If you have a documented browser support matrix that includes anything older than Safari 16.4, set build.target explicitly instead of trusting the default.

    9. Plugins mostly just work — with two real exceptions

    Rolldown implements the same plugin API as Rollup, and the framework plugins that matter are already updated: @vitejs/plugin-react v6 uses Oxc instead of Babel for the Refresh transform (v5 still runs fine on Vite 8 if you haven’t upgraded it yet), and @vitejs/plugin-vue needs no changes. Where it actually breaks:

    • Plugins that lean on the moduleParsed hook: it’s documented as not called during dev at all, to avoid a full AST parse on every file.
    • Plugins built against esbuild’s own onLoad/onResolve plugin format (not Rollup’s) — those are a different API entirely and Rolldown doesn’t speak it. If a plugin’s README mentions “esbuild plugin,” check for a Rolldown-native replacement before assuming it upgrades for free.

    When should you upgrade?

    You run Vite directly, already on 7, no exotic CJS dependencies: upgrade now. The build-time win is real and the breaking surface is small if you don’t rely on manualChunks as an object.

    You’re on Vite 6: go through 7 first. Vite maintains a rolldown-vite package that’s “Vite 7 with Rolldown, nothing else” specifically as an intermediate step — use it to isolate the bundler change from the version-jump change.

    You got here via Astro 7 (or Nuxt, SvelteKit, similar): you’re already running it. The move isn’t “should I” — it’s auditing your existing vite.config for rollupOptions.output.manualChunks as an object and any commonjsOptions overrides, since those are the two that fail or go silent without you touching the framework version at all.

    Your team runs Yarn PnP: wait, or pin to [email protected] and watch the open issues before moving to Vite 8 proper.

    You maintain a Rollup plugin with heavy moduleParsed or output-hook usage: budget real time, not a config tweak — that’s an API-shape problem, not a rename.

    Further reading:

    Frequently asked questions

    Compartir

    Search

    Tags

    PHP Tutorial Laravel JavaScript AI Migration Web Development Best Practices Upgrade Security Laravel 13 Backend SEO Claude Tools