Astro vs Next.js SEO: Core Web Vitals and the Catch
Astro vs Next.js SEO compared on Core Web Vitals: Astro's zero-JS islands win by default, Next.js Server Components close most of the gap. How to pick.
Astro vs Next.js SEO compared on Core Web Vitals: Astro's zero-JS islands win by default, Next.js Server Components close most of the gap. How to pick.

Astro vs Next.js SEO comes down to one variable neither framework can dodge: how much JavaScript reaches the browser before your Core Web Vitals scores lock in. Get that variable right and canonicals, sitemaps, and structured data are a solved problem in both frameworks. Get it wrong and no amount of metadata tuning saves a slow page.
Astro wins Core Web Vitals by default for a content-only blog: its islands architecture ships no JavaScript unless a component asks for it, so Largest Contentful Paint (LCP) and Interaction to Next Paint (INP) start clean without any tuning. Next.js's App Router closes most of that gap with Server Components and streaming, and pulls ahead the moment the site needs auth, a dashboard, or per-user content sitting next to the blog.
Neither answer is universal, and that is the actual decision repo-based blog owners face. A marketing site with a blog bolted on has different constraints than a SaaS product with a blog living inside the same app as the dashboard. The rest of this post works through why JavaScript weight drives the scores, where each framework earns its keep, and how to keep the SEO fundamentals airtight regardless of which one you pick.
Every kilobyte of JavaScript the browser downloads, parses, and executes competes with the work of painting your content and responding to a click. A framework's default JavaScript footprint is not a cosmetic detail; it is the single biggest lever most sites have over their Core Web Vitals scores, ahead of image optimization, font loading, or CDN choice.
That lever matters because most sites are still failing the test. The 2025 Web Almanac measured that only 48% of websites achieve "good" Core Web Vitals on mobile and 56% on desktop, against the standard thresholds of LCP at or under 2.5 seconds, INP at or under 200 milliseconds, and Cumulative Layout Shift (CLS) at or under 0.1. Just over half the web clears the bar on desktop; fewer than half do on mobile, where JavaScript's cost in parse and execution time is highest.
LCP measures how long it takes the largest visible element, usually a hero image or the main heading, to render. CLS measures how much visible content shifts unexpectedly after it first appears, the classic case being an ad or image that loads late and pushes the text you were reading down the page. INP measures how quickly the page responds to a user's interaction, replacing the older First Input Delay metric with a measure that covers the full interaction, not just the first one.
All three are sensitive to JavaScript in different ways. A large JS bundle delays LCP because the main thread is busy parsing and executing instead of painting. It hurts CLS when late-loading scripts inject content into a page that already rendered without reserving space for it. It hurts INP directly: a busy main thread cannot respond to a click until it finishes whatever JavaScript task it is already running.
Astro's core mechanism is the islands architecture: every UI component renders to static HTML and CSS by default, with all client-side JavaScript stripped out automatically. Interactivity is opt-in per component through a client:* directive, so a comment widget or a search box ships its own JavaScript while the surrounding article, headings, and images ship none.
Astro's own documentation is direct about the reasoning: "This avoids the monolithic JavaScript payloads that slow down the responsiveness of many other, modern JavaScript web frameworks." For a blog post with no interactive elements at all, that means the page can ship effectively zero JavaScript and still render the full page, images included, which is why Astro's default Core Web Vitals scores for content sites are hard to beat without deliberate effort in another framework.
The reputation Next.js has for heavier pages comes from its Pages Router era and from React apps in general, where every component, including static ones, shipped as client-side JavaScript to be hydrated in the browser. The App Router changes the default: pages are Server Components unless marked otherwise, and Server Components render on the server with their code and dependencies never sent to the client at all. A blog post with no interactive widgets can be built entirely of Server Components and ship no more JavaScript than an equivalent Astro page.
Streaming is the other half of the story. The App Router streams HTML in chunks aligned to <Suspense> boundaries instead of waiting for every data fetch to resolve before sending anything. Next.js's own guidance is blunt about the alternative: "Without streaming, the server waits for all data before sending any HTML, so TTFB equals the slowest query. With streaming, the server sends the static shell as soon as it's ready." That static shell, your layout, navigation, and fallback content, paints immediately, and Next.js's own advice is to keep the LCP element (a hero image or the main heading) outside any Suspense boundary so it renders in that shell rather than waiting on a slow fetch.
Streaming also improves INP through selective hydration: each Suspense boundary hydrates independently, so React can prioritize hydrating whatever section the user is actually touching instead of blocking on the whole page in one pass. None of this is theoretical. Frigade's own case study moved a client-rendered Pages Router site to Server Components on the App Router. Bundle size dropped 62%. Speed Index, measured with Pingdom Speedtest and PageSpeed Insights, came in 63% faster. That gap did not come from a framework limitation; it came from an architecture the App Router was built to fix.
If the site is mostly text, images, and links, with a handful of interactive widgets at most, Astro's default gets you a fast, low-JavaScript page without having to think about it. This is Vercel's own framing too, and Vercel maintains Next.js, so it has no reason to undersell Astro: Vercel's comparison recommends Astro for "purely static content sites," naming blogs, documentation portals, marketing sites, and portfolios specifically, and describes its strength as shipping "minimal client-side JavaScript" with "isolated interactivity" for the few components that need it, like a search bar or a signup form.
That is the profile of most repo-based blogs: a founder or a small team publishing posts as Markdown files, with a comment widget or a newsletter signup at most for interactivity. For that shape of site, reaching for Astro is not a performance hack, it is matching the tool to the job.
The moment the site is not just a blog, when the same repo also serves a logged-in dashboard, a checkout flow, or content that varies per user, Next.js's App Router earns its extra weight. Server Actions let a form submission run a mutation on the server. The caching and revalidation system then returns updated data and re-rendered UI in a single round trip, commonly gated behind an auth() check inside the action itself.
Astro does not compete on this ground by design. Astro has no official first-party authentication solution; auth runs through community integrations or third-party providers like Supabase, Firebase, or Better Auth, wired up through Astro's middleware and context.locals. That works, but it is assembled, not built in. Vercel's own comparison puts it plainly: Next.js is "the better choice" for "SaaS dashboards, collaborative tools, marketplaces, and commerce apps where every route involves server-side logic and user-specific data," and frames it as "the safer starting point" for a site that might grow from static content into app-like interactivity, since that growth does not require a framework migration.
Astro's answer to that gap is narrower but real. Server Islands, enabled with a server:defer directive, let a mostly-static page render instantly with fallback content while one specific dynamic or personalized component, a logged-in user's avatar, say, fetches and streams in separately, without making the rest of the page dynamic.
That closes a meaningful slice of the personalization gap without adopting Next.js's full application model: a content site can show "Welcome back, Alex" in the corner while the article itself stays static and fast. It does not give Astro Server Actions, a first-party auth story, or the caching and revalidation system Next.js builds mutations around. For a blog with one personalized widget, Server Islands are usually enough. For an app where most routes need session state, Next.js is still the more direct route.
Build time comes up in every framework debate, and for a blog-sized repo, it should not decide anything. Both frameworks statically generate content at build time, Astro by default, Next.js through generateStaticParams in the App Router, and a repo with a few hundred Markdown posts builds in well under a couple of minutes on either one. The variable that actually separates them is runtime JavaScript weight, not the minutes your CI spends building the site. If build time is the deciding factor in your framework choice, that is usually a sign the real question, how much JavaScript ships to readers, has not been asked yet.
Whichever framework you pick, the technical SEO fundamentals do not change: a self-referencing canonical, a sitemap that reflects your actual URLs, and structured data that validates. Both frameworks handle all three; the mechanics just differ.
In the Next.js App Router, each page's metadata, including its canonical URL, comes from generateMetadata, and sitemap.ts generates the sitemap, with a generateSitemaps function available to split output once you approach Google's cap of 50,000 URLs per sitemap file. These are Route Handlers, so they are cached by default. If you want that correctness enforced automatically rather than eyeballed per PR, our GitHub Actions SEO checks post covers a CI job that parses the built HTML for a missing canonical or a mismatch before merge.
Astro's equivalent is the @astrojs/sitemap integration, which generates sitemap-index.xml and sitemap-0.xml at build time once you set the site option in astro.config. The one gap worth knowing up front: it cannot generate sitemap entries for dynamic routes when the site runs in SSR mode, which matters if you lean on Server Islands for personalized routes alongside a mostly-static blog.
Neither framework does anything magic here; both just give you a place to put the JSON-LD and the robots directives correctly. Next.js's robots.ts and sitemap.ts file conventions and Astro's config-driven equivalents both compile to the same static output Google reads. The mistake that actually costs rankings is not a framework limitation, it is a malformed JSON-LD block or a canonical pointing at the wrong URL shipping quietly because nobody checked the built HTML before merge.
| If your repo is... | Lean toward |
|---|---|
| A blog, docs site, or marketing site with no logged-in area | Astro |
| A blog that will always stay separate from any app/dashboard | Astro |
| A blog living inside a product repo that already has auth, a dashboard, or Server Actions | Next.js |
| Planning to add personalization, checkout, or user accounts later | Next.js |
| Only need one or two personalized widgets on otherwise static pages | Either: Astro Server Islands or Next.js Suspense both cover this |
| Migrating an existing Next.js app and adding a blog to it | Next.js, don't split frameworks for one section |
We ran this exact checklist on our own site. Trylyra.ai is a marketing page plus a blog with no auth and no dashboard, the textbook case for Astro. We built it on Next.js's App Router anyway, because the same repo also needs to grow into the product dashboard later, and splitting frameworks for one section was not worth maintaining two build pipelines for a team our size. That is the trade-off this checklist is for: it is not always the framework with the better default score, it is the one that matches what the rest of your repo already is.
If none of the app-like requirements apply, default to Astro and take the Core Web Vitals win with less engineering effort. If the blog shares a repo with a product that already needs auth or a dashboard, Next.js's App Router gets you comparable scores with one codebase instead of two. Either way, the framework choice is a one-time decision your SEO strategy does not depend on nearly as much as the discipline you bring to canonicals, sitemaps, and shipping verified content on top of it.
For teams whose blog already lives in one of these repos and just needs posts written and reviewed without babysitting the frontmatter, that is the exact slot our AI blog writer for developers is built for: it reads your repo, drafts in your voice, and opens a pull request against whichever framework you picked. If you want to see how that looks against your own stack, request early access and tell us which of the two you are on. The workflow is the same either way, a Git-based AI blog writer commits a .md file to a branch and opens a PR, since neither Astro nor Next.js changes what a reviewable diff looks like.
Whether your blog runs on Astro or Next.js, Lyra reads your repo's conventions and opens a pull request that fits either one. Talk to the founder → · Join the waitlist
FAQ
For a content-only blog, usually yes, and by default. Astro renders every component to static HTML and strips client-side JavaScript unless a component explicitly opts into a client:* directive, so a typical post ships close to zero JavaScript. Next.js can match that with the App Router's Server Components and streaming, but it takes deliberate architecture, not a default setting.
Largely, yes. Next.js App Router pages are Server Components by default, so server-only code and its dependencies never reach the client bundle, and streaming lets the static shell (including your LCP element) render before any slow data resolves. Frigade measured a 62% JS bundle reduction and a 63% faster Speed Index after moving a client-rendered Pages Router app to Server Components, which shows how much of the old Next.js weight was avoidable rather than inherent.
Both handle core technical SEO, canonicals, sitemaps, structured data, robots files, fine, so the choice is not really about SEO. It is about Core Web Vitals effort and what the site needs beyond the blog. Astro gets you there with less engineering discipline; Next.js gets you there with more control if you also need auth, a dashboard, or personalization.
They remove the need for some of it. Astro's server:defer directive lets a mostly-static page render instantly with fallback content while one dynamic, personalized component streams in separately, so a logged-in user's avatar or a live cart count no longer forces the whole page into a dynamic render. It narrows the gap; it does not give Astro Next.js's full Server Actions and auth ecosystem.
Not directly, Google ranks content and technical correctness, not the framework name, but a migration can absolutely break rankings if canonicals, redirects, or sitemaps regress in the process. Treat a framework migration like any other technical SEO project: verify every canonical and redirect before and after, and gate the change behind CI checks rather than a manual spot check.
Built by the tool you're reading about
Lyra finds the topics worth ranking for, writes them in your repo's voice, fact-checks every claim, and opens a pull request scored and ready to merge. You review and hit merge. Want to see what she'd write for you? Tell us about your blog and the founder will walk through it with you.
Keep reading

Autonomous AI SEO agents range from auto-publish to PR-approval. See how the control models compare, and what CNET and Sports Illustrated show about the risk.

ChatGPT for blog writing looks free until you count the hallucinated stats, dead links, duplicate posts, and editing hours a raw draft quietly costs you.

Jasper vs Surfer SEO in 2026: Jasper writes, Surfer optimizes, and their native integration just got discontinued. What stacking both really costs now.