I originally built my website with Flutter. Just a simple home page, about, and contact. Nothing fancy. I had plans to add a blog section but never got around to it.
Flutter’s great for mobile apps, but on the web it has some rough edges: packages that don’t support web, dart:io compatibility issues, weird image rendering quirks, and SEO that’s more trouble than it’s worth. For a simple content site, these friction points added up. Time to rebuild it with actual web technologies.
Trying React
So naturally, React came to mind first. When you think “web development,” you think React. It’s everywhere, every job posting wants it, every tutorial assumes you’re using it. Back when I did web dev, I worked with Vue.js and did a bunch of PHP/Laravel stuff, but React still felt like the obvious first choice. Everyone’s using it, so I figured I might be missing out on something.
Turns out it’s way more complex than I expected.
React has this mental model where you’re constantly thinking about renders, dependencies, when effects run, what causes what to update. For something as simple as “show some text on a page,” you’re managing state and lifecycle hooks. Coming from Flutter, I knew there’d be a learning curve, but damn, the conceptual overhead was heavier than I thought.
And that’s before you even get to the ecosystem. The number of decisions you have to make before writing any actual code caught me off guard: bundler, framework, router, state management, TypeScript config, linting, formatting. Each one has like five “right” answers depending on who you ask.
I ended up spending days reading about the “correct” way to structure a React app instead of just building a website. Back when I did web dev, you just… made a website. The modern tooling is powerful for sure, but man, there’s a lot of upfront complexity.
Finding Astro
So I gave up on React and started looking for alternatives. I found Astro mentioned in some random Reddit comment, someone describing it as “just write HTML and CSS with modern tooling.” The pitch was simple: ship actual HTML pages instead of JavaScript apps that render HTML.
Sounded almost too simple, but I figured I’d give it a shot.
A weekend later, I had a working site with the blog section I’d been putting off for months.
What I ended up with
The project structure is straightforward — here’s a compact directory example:
src/
├─ components/ # reusable UI components
├─ layouts/
│ └─ BaseLayout.astro # all pages use this
├─ pages/
│ ├─ index.astro # homepage
│ ├─ blog/ # blog posts
│ └─ ... # other pages (about, etc.)
└─ styles/ # SCSS styles
└─ utils/ # utility functions
The killer feature for me: blog posts are just markdown files with frontmatter. No JSX, no components for paragraphs, no complex setup.
---
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 top YAML block (the lines between the --- markers) is called “frontmatter.” It stores metadata like title, date, description, tags, and any other fields your templates or build tools might need. Astro reads those values automatically so your layout can display the title, sort posts by date, or filter by tags without extra code.
Here’s what each directory handles:
-
Components — reusable UI bits. In my case, things like the command bar and that spinning ASCII art sun you see on the homepage. Think of them as building blocks you can drop into multiple pages without copy-pasting code everywhere.
-
Layouts — wrap your pages with common structure.
BaseLayout.astrohandles the HTML skeleton, meta tags, and shared elements that every page needs. Write it once, use it everywhere. Pages just specify which layout to use in their frontmatter. -
Pages — where the actual content lives. Each file here becomes a route on your site.
index.astrois the homepage,about.astrois/about, and so on. Theblog/subfolder contains all my blog posts as markdown files, which Astro automatically turns into pages. -
Styles — keeps things organized with SCSS.
_base.scsshas the core CSS rules,main.scssimports everything and defines color variables, and page-specific files like_index.scssand_blog.scsshandle styling for individual sections. If a page needs unique styles, it gets its own file. Otherwise, it reuses the shared stuff. -
Utils — helper functions. Mine has
seo.tswhich generates all the meta tags, Open Graph stuff, and other SEO-related markup so I don’t have to manually write that out for every page.
Astro automatically generates pages from these Markdown files, treats the frontmatter as metadata, and exposes those fields to layouts and collection queries, which makes writing and publishing posts fast and low-friction.
Why it works for my specific needs
Astro just happened to match what I was actually trying to build: a simple personal site with a blog. I’m not building some complex app with tons of interactivity, so the HTML-first approach made way more sense. Pages load as actual HTML and CSS, with JavaScript only where I explicitly add it.
The content collections feature is basically designed for sites like this. Blogs, portfolios, documentation, and the like. I can define a schema for my posts, get TypeScript autocompletion, and Astro handles all the page generation automatically.
Coming back to web dev after years in Flutter land and getting overwhelmed by React’s ecosystem, having fewer decisions to make was exactly what I needed. I could actually focus on writing content and building pages instead of spending days configuring build tools.
The dev experience is also just smooth for content sites. Hot reload works properly, builds are fast, and I’m not fighting the framework to do basic stuff like adding a new blog post or tweaking a layout.
Final thoughts
Going into this, I thought React would just… work. That I’d pick it up quickly and have a site running in no time. Turns out that’s not really how it goes.
But here’s the thing. React isn’t bad. It’s just that maybe we shouldn’t default to “React first” for every web project. The right tool depends on what you’re actually building:
- Building a big interactive app with complex state? Use React (or Vue, Svelte, whatever).
- Building a blog or portfolio site like this one? Use Astro.
- Building a Flutter web app? Honestly, I don’t know who actually uses Flutter web. If you insist and really like Flutter, it’s great, just… as a Flutter developer myself, there are better tools out there for web stuff.
Astro worked for what I needed: simple personal site with a blog that loads fast. It’s not some revolutionary framework, just happened to fit what I was trying to do.
The code for this project is on GitHub if you’re curious.