Astro 6 shipped on March 10. We moved this site over a few weeks later, once the early 6.0.x patches settled. Short post on what changed, what broke, and the one feature that was genuinely worth the upgrade.

Context

aurabyt.com is a small Astro site. A dozen or so pages, a blog collection, a portfolio collection, hosted on Vercel in SSR mode. Not a stress test, but a realistic example of what a small business site on Astro looks like.

We were on 5.x before. The upgrade was mostly a matter of bumping the version, running the build, and fixing what yelled.

What was painless

Most things. The adapter updated cleanly, the content collections still work the same way, MDX still renders, and the build finished green on the first proper pass. Astro has taken backwards compatibility seriously across major versions and it shows.

The dev server feels noticeably faster. That’s the Vite Environment API refactor doing its job: dev now runs your actual production runtime, so the “works locally, breaks in production” class of bug is genuinely smaller. I ran into that exact bug twice in the last year on 5.x. It was worth an afternoon to stop running into it.

The Fonts API was the real reason to upgrade

The feature we actually cared about was the built-in Fonts API, which landed behind an experimental flag back in 5.7 and went stable in 6.0. Before, we were pulling fonts from a CDN (Google Fonts or Bunny Fonts) which meant an extra DNS lookup, an extra TCP handshake, and a request to a third party on every cold visit.

With the new API, you declare your fonts in astro.config.mjs and Astro handles the rest: downloads them at build time, self-hosts them, generates the right @font-face rules, and wires up preload hints for the weights you use above the fold.

Concretely, on this site:

  • Two external requests gone.
  • A measurable LCP improvement on cold loads from mobile, especially on networks where the third-party font host wasn’t already cached.
  • One fewer thing to trust.

The API is also short enough that the whole font configuration is maybe fifteen lines. It’s the kind of feature that should have been built in from the start.

What did break

Two things, both minor:

  • A couple of our scroll-reveal animations were using the old view-transition hook signature. Trivial rename.
  • A third-party integration for image optimisation hadn’t published an Astro 6 compatible version at the time of upgrade. We were able to swap to Astro’s built-in image handling without much fuss.

Nothing that required rethinking anything structural.

Should you upgrade?

If you’re running a production Astro site in 2026, yes, at your convenience. The dev server improvements alone are worth it, and the Fonts API is a real win. There’s no reason to rush (5.x is stable and supported) but I’d plan for it within a quarter.

If you’re on 4.x or earlier, the upgrade path is longer because the content collections syntax changed between 4 and 5. That’s a separate afternoon.

Cloudflare’s acquisition of the Astro company in January raised some questions about long-term direction. From what’s shipped since then, the framework is still MIT-licensed, still independently governed, still prioritising the things that make it good at static and hybrid sites. We’re not planning to move off it.

Update, August 2026: we’re on Astro 7 now

Astro 7 shipped on June 22, about three months after 6. This site is running it. Since the post above is the version of “should you upgrade” we’d give a client, here’s the same answer for the next number.

The headline of 7 is speed, and it’s not incremental. The .astro compiler was rewritten in Rust, the Markdown pipeline was replaced with a Rust-powered one, and Vite 8 brought the Rolldown bundler in place of esbuild and Rollup. Astro’s own benchmarks put build times 15 to 61 percent faster, with astro.build itself going from about 63 seconds to 24. On a site this size the absolute saving is small, but the same work makes the dev server noticeably quicker, and that’s what you actually feel.

Two things worth knowing before you schedule the afternoon:

  • Markdown rendering changed. Sätteri, the new Rust Markdown and MDX pipeline, is the default in 7 and replaces the remark and rehype stack. It’s stricter: markup is treated as written rather than auto-corrected, unclosed tags and unterminated attributes are errors now, and whitespace between elements collapses following JSX conventions. If you have a content collection full of hand-written Markdown with sloppy inline HTML, that’s where your breakage will be. We sidestepped this by adopting Sätteri early, back when it landed in 6.4, so by the time 7 arrived our Markdown output was already settled and the upgrade didn’t touch it. That’s the trick worth stealing: move the risky part on its own schedule, not on the major version’s.
  • Shiki and a strict CSP no longer mix. This one cost us a real debugging session. Astro’s default syntax highlighter colours every code token with an inline style attribute, and inline attributes can’t be hashed the way an inline <style> element can, so a Content Security Policy without unsafe-inline for styles strips them. Astro removed support for the combination deliberately and points at Prism instead. We switched, which emits CSS classes we can colour from our own stylesheet. Nothing looked broken beforehand because no post here had a code block yet, which is the worst way for a bug to wait for you.

Node 22 is the new floor. Route caching graduated out of experimental with a platform-agnostic API, and there’s a new src/fetch.ts entrypoint if you want real control over the request pipeline.

Same recommendation as before, one version up: if you’re on a supported 6.x, plan the upgrade within a quarter rather than rushing it, and read the Markdown notes first because that’s the part with teeth. npx @astrojs/upgrade handles the mechanical half.


If you’re trying to decide between frameworks for a new small-business site in 2026, Astro remains our default. Send us a note if you want a second opinion on your stack.

Update, September 2026: the upgrade argument nobody makes, which is the dev server

Everything above weighs a version upgrade on speed, features and breakage. There is a fourth axis we had not thought about until this week, and it turns out to favour staying current more strongly than any of the benchmarks do.

Astro’s dev server is Vite’s dev server. That means Astro inherits Vite’s security posture exactly, including the list of files the dev server refuses to serve, and that list is not the same on every version.

Reading the declared ranges off the npm registry this morning: Astro 6.4.8 depends on vite: ^7.3.2, and Astro 7.3.2 depends on vite: ^8.0.13. That looks like a detail until you know that Vite’s default server.fs.deny blocklist was extended in Vite 8.1.0 on June 23, adding .npmrc, .yarnrc.yml and the full set of private-key extensions to the .env and *.{crt,pem} patterns that were there before. A caret range on 7.x can never reach 8.1, so an Astro 6 project cannot get that hardened list by upgrading Vite within its supported range. It has to be configured by hand.

We tested this rather than assuming it. On Vite 7.3.6, the newest 7.x release, with default configuration, a request for .env returns 403 and a request for .npmrc, which holds an npm auth token on most machines, returns 200 with the token in it. On this site, running Astro 7.2.4 on Vite 8.2.2, every equivalent request returns 403, including the five query-parameter bypass strings from CVE-2026-39364, which is being mass-scanned right now.

None of this touches a built and deployed site, and it only matters at all if a dev server has been exposed to a network with --host or from inside a container. But it is a real argument for keeping the major version current that does not show up in any release note, because the change that mattered shipped as a feature rather than a fix. The full write-up of the Vite flaw includes the config block to paste into astro.config.mjs if you are staying on 6.

One more version note while we are here: the current Astro release is 7.3.2, and this site is on 7.2.4. That gap is patch releases, not a decision, and it is on the list.