I Stopped Fighting My Static Site When I Switched to Astro
I’ve rebuilt my personal site more times than I care to admit.
Next.js first. Then SvelteKit because Next felt heavy for a site that’s mostly text. Then back to Next because the ecosystem is just easier. Each time I ended up in the same place: fighting the framework to ship a bunch of HTML pages that don’t need a JavaScript runtime.
Astro is the first one that didn’t make me fight.
The Mental Model Is Different
Every other framework starts from the assumption that you’re building an app. Static output is a feature you opt into — SSG mode, export, generateStaticParams, whatever they call it. The default is dynamic. The default is JavaScript.
Astro flips this. The default is zero JavaScript. If you want JavaScript in the browser, you have to ask for it. You opt in with client:load or client:idle or client:visible. The rest is just HTML and CSS.
That inversion changes everything about how you think while building. You’re not stripping things out. You’re adding exactly what you need.
Content Collections Actually Solve Something
Before Astro, managing MDX content was always a little janky. You’d have some folder of markdown files, a loader, some frontmatter types you’d document in a comment somewhere and eventually forget to update. TypeScript integration was an afterthought.
Astro’s Content Collections give you a schema you define once in config.ts:
const blog = defineCollection({
schema: z.object({
title: z.string(),
pubDate: z.date(),
category: z.string(),
readingTime: z.number(),
draft: z.boolean().default(false),
}),
});
After that, every post is validated at build time. Wrong date format — build error. Missing required field — build error. You get autocomplete on frontmatter and TypeScript knows the shape of your data everywhere. It’s the kind of thing that should have existed years ago.
.astro Files Are Weird Until They’re Not
The file format threw me off at first. The frontmatter-style script block at the top, the HTML below, the scoped styles at the bottom. It looks like three different languages stapled together.
---
const { title } = Astro.props;
---
<h1>{title}</h1>
<style>
h1 { color: red; }
</style>
After a day or two it clicks. The script block runs at build time — it’s not client JavaScript, it’s just the logic for generating this particular piece of HTML. Once you internalize that, the format makes a lot of sense. You’re writing a template, not a component.
The Output Is Dumb HTML. That’s the Point.
I opened the dist/ folder after my first build and it was just… HTML files. Index.html with actual content in it. CSS files. A handful of JS chunks for the interactive bits I’d explicitly opted into.
No hydration payload. No client-side router bootstrapping. No JSON blobs of server props. Just the page.
The performance falls out naturally from this. There’s nothing to optimize because there’s nothing there. First paint is fast because the browser receives the content directly, not instructions for how to assemble it.
For a site that’s mostly blog posts and app pages, this is exactly right. I don’t need React in the browser. I needed someone to build my HTML at deploy time and get out of the way.
What Astro Is Not
It’s not a replacement for Next.js if you’re building something with auth, real-time data, or complex interactivity. The Islands architecture — where you sprinkle interactive components into otherwise static pages — works well for things like search or a carousel. It doesn’t work well when most of your page needs to react to user state.
For a portfolio, a blog, a docs site, a marketing page: Astro is the right call. For a SaaS dashboard: use something else.
One Rough Edge
The ecosystem is smaller. If you need a specific component library or integration, there’s a decent chance you’ll be writing your own adapter or leaning on the community for something half-maintained. Next.js wins on ecosystem breadth, full stop.
It’s a tradeoff I’m comfortable with for this project. The things Astro does well, it does really well.
Where I Landed
This site is built with Astro 5, Tailwind CSS 4, and MDX for content. The whole thing deploys to GitHub Pages in under a minute. The HTML is clean, the CSS is scoped, and there are maybe three components that ship any JavaScript at all.
Most importantly, I don’t think about the framework anymore. I open a file, write, build, deploy. That’s it. The best tools disappear into the work.
Astro disappeared.