← Back to Tech Radar

Astro 5+

Ring: Adopt Quadrant: Languages and Frameworks

Our verdict

Default for content-heavy headless front. Zero-JS islands win on Core Web Vitals.

Practitioner brief

Why we adopted it

We moved wppoland.com from Next.js 13 pages-router to Astro 5 in March 2026. LCP on the homepage went from 2.4s to 1.1s on a Moto G Power profile, the JS bundle on a content page dropped from 187 KB gzipped to 9 KB (a single Search island), full-site cold-build time fell from 11 min 30s on Vercel to 7 min 30s locally on the 16 GB heap in scripts/stable-build.sh. Content Layer API (RFC 0050, Astro 5.0) treats MDX, JSON, and remote content under one getCollection surface, collapsing three adapters from the Next.js era.

When we reach for it

Content-driven marketing surfaces: pillar pages, comparison matrices, programmatic city pages, docs, blogs. Render mostly static, islands isolated (search, a pricing toggle, a chart), editor loop through Markdown plus MDX collections. We do not reach for Astro when the brief is application-shaped: authenticated dashboards, checkouts with shared cart state, anything where the right model is client-rendered React or RSC streaming. For those we stay on Next.js 15.

Upgrade path

Most teams arrive from Next.js 13/14 pages router (cleanest path, getStaticProps maps almost 1:1 to Astro collections), Gatsby v5 (GraphQL schema is the hard part; file router and MDX port fine), or a WordPress monolith going headless (treat it as greenfield, wire WPGraphQL or REST). What does not transfer: React context, client-only state (Zustand, Jotai), Next.js middleware. Plan ~1 day per 30 content pages plus a hard week for React-to-Astro shell conversions.

Two production scars

First, View Transitions on iOS Safari 17.4: clicking an MDX-driven link during a transition fired new island scripts before the old DOM was swapped, leaving stale listeners attached and search broken on the second navigation. Workaround: transition:persist="search" and <ClientRouter /> instead of the legacy <ViewTransitions /> import (Astro PR #12029 stabilised this in 5.2). Second, MDX plus remark-shiki on a Cloudflare Pages build: shiki tried to load 90+ grammars and OOM'd a 4 GB worker. Fix: pin shikiConfig.langs to ['ts', 'js', 'php', 'json', 'bash']. Build memory dropped from 3.8 GB to 1.2 GB.

What we are watching

Server Islands (Matthew Phillips, RFC 0040, in 5.0) is the path to selective dynamic personalisation inside a static page; we are piloting it on the pricing toggle but holding off site-wide until caching headers stabilise (astro/#11437). Container API for component testing under vitest is on our shortlist once Bjorn Lu's PR #11952 ships. And Astro DB: Turso bought it back in early 2026 and the migration story for astro:db sites is still open (astro/#12188).

Added: 2026-04-26 · Last reviewed: 2026-04-26

Related reading