My website started its life in Flutter. It was simple enough: home, about, and a contact page. Nothing wild. I always meant to add a blog, but I kept putting it off because, well, Flutter on the web works, but it feels like you’re fighting the medium.
It’s fantastic for apps, don’t get me wrong. But for a content site? You’re dealing with packages that break on web, weird dart:io issues, text rendering quirks, and SEO that feels like a hackathon project. For a simple portfolio, the friction just wasn’t worth it. I pulled the plug and decided to rebuild with actual web tech.
The React Trap
Naturally, I looked at React first. It’s practically synonymous with “modern web development” at this point. Every job post asks for it; every tutorial defaults to it. Even though my background was more Vue and old-school PHP/Laravel, I figured React was the “correct” choice in 2025.
Turns out, “popular” doesn’t mean “simple.”
React forces a specific mental model on you. You’re constantly juggling renders, dependency arrays, side effects, and state, even for static content. I found myself over-engineering a solution for “display text on screen.” The conceptual overhead felt surprisingly heavy for what should have been a lightweight project.
And then there’s the ecosystem fatigue. Before writing a line of code, I was vetting bundlers, routers, state management libraries, and linting rules. I spent days reading “Best Practices for 2025” articles instead of actually building the site. It felt… noisy.
Stumbling onto Astro
Frustrated, I started digging for alternatives and caught a mention of Astro in a random Reddit thread. The pitch was refreshing: “just write HTML and CSS, ship zero JS by default.”
It sounded like the way web development used to feel, before we started sending 2MB of JavaScript to clear a div. I was skeptical, but curious.
A weekend later? I had the entire site ported, plus the blog section I’d been procrastinating on for months. It just clicked.
How it’s set up
The structure is super clean. It doesn’t feel like an “app”; it feels like a website.
src/
├─ components/ # reusable UI bits
├─ layouts/
│ └─ BaseLayout.astro # the master template
├─ pages/
│ ├─ index.astro # homepage
│ ├─ blog/ # where the markdown lives
│ └─ ... # etc.
├─ styles/ # SCSS
└─ utils/ # plain TS helpers
The killer feature is how it handles content. Blog posts are literally just Markdown files. No CMS to configure, no database, no complex JSX-to-HTML pipelines.
---
title: 'My Post'
date: '2025-09-19'
description: 'Just a regular blog post'
tags: ['web', 'astro']
---
# This is just markdown
And it works exactly like you'd expect.
That YAML block at the top (frontmatter) handles all the metadata. Astro just reads it. I didn’t have to write a parser or build a custom API to fetch my own posts.
Here’s a quick breakdown of the moving parts:
- Components: I use these for little self-contained pieces, like the command bar or that spinning ASCII sun on the homepage. They’re just reusable blocks of HTML/CSS/JS.
- Layouts:
BaseLayout.astrodoes the heavy lifting for the HTML skeleton, meta tags, basic structure, styles. Every page just wraps itself in this. - Pages: This is the magic part. The file system is the router.
index.astrois home.about.astrois/about. Theblog/folder holds the markdown files, and Astro turns them into routes automatically. - Styles: Standard SCSS setup. Variables in one place, base styles in another. It’s simple and it works.
- Utils: Just some Typescript helpers. I have a
seo.tsfile that automates the meta tags so I don’t forget them.
Why it stuck
Astro just fit the problem I was solving. I wanted a personal site, not a Single Page Application. I didn’t need client-side routing or complex state management; I needed HTML that loads fast.
The “frontmatter” feature is a godsend for blogs. I get type safety on my frontmatter (so I can’t accidentally publish a post without a date), and it handles all the build-time generation.
It feels like making a website in the good old days. You’re writing actual HTML, CSS, and JS, but with the power of modern tooling. I stopped fighting the tools and started writing content again. Development is fast, simple, and honest.
Final thoughts
I went into this assume React was the default answer. I was wrong.
React isn’t “bad,” obviously. If I were building a dashboard or a complex interactive app, I’d pick it up in a heartbeat. But for a blog? A portfolio? A documentation site? It’s overkill.
- Big, state-heavy app? React/Vue/Svelte.
- Content-focused site? Astro.
- Flutter web? Look, I love Flutter, but… maybe let’s keep it on mobile for now.
You can check out the source on GitHub.
Edit (2026-01-27)
I actually ended up migrating the blog posts from src/pages to src/content for Astro’s Content Collections. Why? RSS. I wanted to serve full-content feeds so you don’t have to leave your reader, and to do that programmatically with Astro’s Container API, collections are the way to go. Plus, now my frontmatter is strictly typed with Zod, so I can’t break the build by typo-ing a date. Totally worth the refactor.