· Ben · engineering · 5 min
Astro vs Next.js for a blog that's mostly posts
Both render Markdown. Only one of them has an opinion about your frontmatter. How to pick Astro or Next.js for a blog by what else lives in the repo.
The site is a homepage, a pricing page, maybe a docs section, and forty markdown files. You're picking between Astro and Next.js, you've read six comparison posts, and every one of them explained partial hydration to you again.
Look at who wrote them. The top results for astro vs next.js blog are a Next.js agency, two headless-CMS vendors, and Vercel's own comparison page. Vercel's is the only one that answers the blog question directly, and it answers in its favor: Next.js can build a fast static blog with minimal config, and starting there leaves room to add auth or dynamic content later. That's a true statement. It's also exactly the shape of argument you'd expect from the company that hosts the output.
None of them mention frontmatter. Both frameworks render Markdown fine. Only one of them has an opinion about the metadata sitting on top of it, and for a site that's mostly posts, that's the whole decision.
The content contract is the difference nobody benchmarks
Astro's content collections validate frontmatter with a Zod schema. The docs are direct about the consequence: schemas enforce consistent frontmatter, and if any file violates its schema, Astro gives you an error. Wrong date format, missing description, a tags field that's a string where every other post has an array. The build fails. You find out in CI, before the merge.
Next.js does not ship that. @next/mdx doesn't support frontmatter by default, and the docs tell you what to do instead: use fs or globby to read the posts directory and extract the metadata yourself. I'm not counting that against it. Next.js treats your content pipeline as application code you own, which is consistent with everything else about the framework.
Sources: Astro content collections, Astro error reference: content entry frontmatter does not match schema, Next.js MDX guide.
The difference shows up on the day someone commits a post with date: 08/14/2026 instead of 2026-08-14. In one setup the build goes red. In the other the post renders, sorts to the bottom of the index, and you find it in Search Console six weeks later when you're wondering why that article never got a single impression. The failure is silent. A post that quietly doesn't exist.
You can buy the guarantee back on the Next.js side, and you probably should. Velite gives you a Zod-validated content layer over the same folder of MDX, with typed output and a build that fails on bad input. It's the sane default now that Contentlayer is unmaintained. Just be honest that it's a dependency you chose and now maintain, versus a thing that was already in the box.
The performance numbers are real and mostly about who picked what
April 2026 HTTP Archive data has 67% of Astro sites hitting a good Core Web Vitals score, with the lightest median page weight in the set. That's a genuinely good number and I don't want to talk anyone out of it.
The same analysis names the caveat: those scores may reflect the kind of sites people build with Astro, and the advantage may narrow as complexity rises. Astro's own 2023 report has the more quotable version, Astro as the only framework above 50% passing with Next.js at roughly one in four. It's three years old, it's published by Astro, and like every study of this shape it measures populations of sites, not the same site built twice.
A framework-population CWV score tells you who picks the framework. It doesn't tell you what your blog will score. Forty pages of prose with one hero image will pass on either one if you don't do something silly with fonts.
What does differ is the default, and defaults are what you get when nobody's paying attention. Astro ships zero JavaScript per page and makes you opt into an island. Next.js ships a React runtime you can shrink but can't delete. On an article page that difference is real and small in absolute terms. Over a year of a team adding one more client component to the layout, it's the difference between a site that stays fast by accident and one that stays fast because someone keeps checking.
Pick by what else is in the repo
Here's the rule I'd actually apply.
If the repo is posts, marketing pages, and nothing that requires a session, use Astro. Content collections, a schema, an [...slug].astro layout, done. You'll write less pipeline code and there's less surface for the site to get slow on.
If the repo already contains the product, use Next.js. Auth, dashboards, API routes, a design system built out of React components you want to reuse in article layouts. Running two build systems in one repo to save 30KB on /blog is a tax you pay every week, and whoever's on call for the deploy pipeline is the one who pays it.
The awkward middle is a blog on a subdomain with its own repo. Astro for the blog is defensible there even when the app is Next.js, and plenty of teams run it that way. Just cost it out first. Two deploys, two dependency trees, and a design system that starts drifting the first time someone changes a heading color in only one of them.
One thing the choice doesn't decide: who writes the posts. If non-technical people on your team need to edit, both frameworks are equally fine and equally irrelevant, because the answer is a git CMS sitting on the same files. That's a separate pick between Decap, Sveltia, Keystatic and Tina, and it's mostly orthogonal to the framework.
The decision is more reversible than the comparison posts imply
Every one of those vendor articles frames this as an architecture commitment. For a blog it mostly isn't.
The .mdx files survive a migration. Your layouts don't. What you're choosing is which layer parses the frontmatter and which template renders the body, and both of those are a weekend of work to rewrite for a forty-post blog. The durable asset is the set of field names you settled on and the slug rule that generates your URLs.
So protect the URLs and stop worrying. Keep /blog/<slug> mapping to the same filename, keep the slug derivation identical, and a framework swap is invisible to Google. Change the URL shape at the same time and you'll spend a month watching impressions recover from a redirect chain nobody tested.
Pick the one that fits the repo today. If it's wrong in eighteen months, that's a branch, not a rewrite.
What neither one gives you
Both frameworks will render a post just fine. Neither has an opinion about whether the post gets written.
That's the failure mode I see. The pipeline is fine, the schema validates, Lighthouse is green, and the most recent article is from March. Framework choice is a two-hour decision that teams spend two weeks on because it feels like progress and writing doesn't.
Contentcron doesn't care which of the two you picked. It reads your existing posts and infers the frontmatter contract from them, the field names, the date format, the slug style, then writes new articles that match and opens each one as a pull request against contentcron/<slug>. If your Astro collection enforces a Zod schema, the generated post has to satisfy it like every other post, because it goes through the same build. Astro, Next.js, Hugo, Gatsby, Eleventy: the repo is the integration.

Review happens where you review everything else, in the PR. If you want the longer argument for that, I wrote it up in review content the way you review code.
If you've got the framework question settled and the publishing question open, that's the one worth solving. First article is free, no card required.