Skip to content
Fran Gonzalez
← Back to blog
(updated Jul 16, 2026)·Clanker·5 min read

Early look at Astro 7 alpha with Vite 8 and Rolldown

Updating this blog to Astro 7 alpha surfaced vite version conflicts, rolldown type incompatibilities, and the fact that pnpm update bypasses minimumReleaseAge.

Some matmuls wrote this slop, sorry. My goal with this content is to document some work I (a real human bean) do while poking the Clanker, and try to learn something along the way.

Astro 7 alpha ships with Vite 8 and rolldown: the Rust-based bundler that replaces rollup. I migrated this blog to test the new stack and hit several issues worth documenting.

Upgrade baseline

Astro 6 uses Vite 7, which bundles rollup as its production bundler. Vite 8 replaces rollup with rolldown, a Rust-based bundler that’s 10-30x faster in benchmarks. The plugin API is compatible, but the type systems are different. Rolldown’s PluginContextMeta has a rolldownVersion property that rollup’s doesn’t.

The @tailwindcss/vite plugin declares vite: "^5.2.0 || ^6 || ^7 || ^8" as a peer dependency. When pnpm resolved it to vite 8 while astro stayed on vite 7, two different bundlers coexisted in node_modules. The type error:

Type 'Plugin<any>[]' is not assignable to type 'PluginOption'.
  Types of property 'meta' are incompatible.
    Property 'rolldownVersion' is missing in type 'MinimalPluginContext'
    but required in type 'MinimalPluginContext'.

This is a known issue: Astro issue #16542 documents the exact same error.

Migration notes

How vite@8 got into the tree

Running pnpm update --latest bumped vitest and other dev dependencies. Some of these pulled in vite@8 as a peer dependency. pnpm resolved @tailwindcss/vite to vite 8 (which it accepts), while astro and @astrojs/vue stayed on vite 7. The lockfile ended up with two vite versions:

pnpm ls vite --depth 1

dependencies:
├─┬ @astrojs/vue@6.0.1
│ └── vite@7.3.5
├─┬ astro@6.4.4
│ └── vite@7.3.5
devDependencies:
├─┬ @tailwindcss/vite@4.3.0
│ └── vite@8.0.16 peer
└─┬ vitest@4.1.8
  └── vite@8.0.16 peer

Postcss detour

Before settling on Astro 7 alpha, I tried switching from @tailwindcss/vite to @tailwindcss/postcss as a local workaround (never committed). The approach:

  1. Removed @tailwindcss/vite from devDependencies
  2. Added @tailwindcss/postcss and postcss
  3. Created postcss.config.ts
  4. Removed the tailwindcss() vite plugin from astro.config.ts

The build worked, but the setup was more complex: an extra config file, an extra dependency, and a departure from both the Astro docs and Tailwind docs, which deprecated the @astrojs/tailwind PostCSS integration in favor of @tailwindcss/vite. I discarded these changes once the Astro 7 alpha route became available.

The real fix: Astro 7 alpha

Astro 7.0.0-alpha.2 depends on vite: "^8.0.13". With astro on vite 8, all packages resolve to a single vite version:

pnpm ls vite --depth 1

dependencies:
├─┬ @astrojs/vue@7.0.0-alpha.0
│ └── vite@8.0.16
├─┬ astro@7.0.0-alpha.2
│ └── vite@8.0.16
devDependencies:
├─┬ @tailwindcss/vite@4.3.0
│ └── vite@8.0.16 peer
└─┬ vitest@4.1.8
  └── vite@8.0.16 peer

I discarded the postcss changes, re-added @tailwindcss/vite@4.3.0, and deleted postcss.config.ts. The vite plugin works natively with vite 8: no conflict.

TypeScript 6

Upgraded from 5.9.3 to 6.0.3. The main breaking change: the default types value changed from auto-including everything in node_modules/@types to [] (empty). Projects that relied on implicit Node.js types suddenly lose process, Buffer, and other globals.

The fix: adding to tsconfig.json:

{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "types": ["node"]
  }
}

The TypeScript 6 migration guide recommends this for most projects. A ts5to6 codemod handles it automatically.

Removing shamefullyHoist

shamefullyHoist: true hoists packages to the root node_modules, which can cause pnpm to resolve peer dependencies to unexpected versions. I removed it to enforce stricter dependency isolation; each package gets only what it declares.

minimumReleaseAgeExclude for alphas

The alpha packages (astro@7.0.0-alpha.2, @astrojs/vue@7.0.0-alpha.0) were published hours before I tried to install them. pnpm’s minimumReleaseAge: 1440 blocked the install. I added temporary exclusions:

minimumReleaseAgeExclude:
  - astro@7.0.0-alpha.2
  - "@astrojs/vue@7.0.0-alpha.0"

These should be removed once the alphas pass the 1-day cooldown window. The third post in the supply chain series covers why exclusion lists need periodic review.

Verification

Astro 6.4 + vite 7.3.2 + rollupAstro 7 alpha + vite 8.0.16 + rolldown
Warmup6.09s0.95s
Run 11.11s0.63s
Run 21.10s0.64s
Run 31.11s0.62s
Run 41.10s0.63s
Run 51.12s0.63s
Median1.11s0.63s
Pages6572

Methodology

Same blog content (verified with git diff ba6cfdc..HEAD -- src/content/blog/; zero changes), same lockfile, same machine. The page count difference (65 vs 72) comes from build-level changes between versions; the vite8 tree has a newer BaseLayout.astro, apple-touch-icon.png, and site.webmanifest.

Both builds ran on a Mac16,10 (Apple M4, 16 GB):

  1. rm -rf dist .astro then pnpm build (warm-up, caches image generation and types)
  2. Five timed runs: rm -rf dist .astro between each, then pnpm build
  3. Median reported

Revisit after stable

pnpm update --latest bypassed the Renovate cooldown flow, pulling in vite@8 before astro supported it. The version conflict surfaced as a rolldown/rollup type mismatch; upgrading to Astro 7 alpha was the fix.

References

This post was written with AI assistance.