How I picked a stack that's equal parts comfortable and chaotic, and why that's the whole point.

I could have built this blog on something sensible. A Next.js template. A Ghost instance. A static site generator pointed at a folder of markdown files, deployed in an afternoon. I've done that before. Many times.

Instead I built sahd.dev on Astro 6, EmDash, TailwindCSS, and Cloudflare Pages. A framework I love, a CMS that's been alive for less than two months, experimental compiler flags I turned on to see what would happen, and a styling solution that's here because someone in this stack needs to be boring.

These are poor decisions. But making poor decisions in public might be the most useful thing this site does.

The CMS Problem (My CMS Problem)

I have a soft spot for content management systems. A genuine, slightly embarrassing fondness. The kind where I'll spend an evening reading documentation for a CMS I have no intention of using, just because the schema model is interesting.

The list I've run in production tells a story: MovableType, Hannon Hill, WordPress, Hugo, Ghost, Strapi, Keystatic. MovableType taught me static generation was a good idea before anyone called it that. WordPress taught me that ecosystem size and software quality are different metrics. Hugo taught me build speed is a feature people will switch platforms for. Strapi taught me headless is great until you need to explain it to a non-developer. Keystatic taught me git-backed content has real legs if you're willing to live in the repo.

So when Cloudflare released EmDash on April 1st, and everyone spent 48 hours figuring out if it was an actual product or an elaborate prank, I was already reading the source code.

Why EmDash

EmDash is a v0.1.0 beta. No plugin ecosystem. No theme marketplace. No community to speak of. Choosing it for a real site right now is objectively hard to defend.

I chose it anyway.

It’s an Astro integration. Not a separate application that Astro talks to over an API, not a headless backend that requires a build step to see changes. You add it to your Astro config and you get a CMS living inside your project: admin panel, REST API, auth, media library. That’s a genuinely different architectural bet than anything else I’ve used, and I wanted to feel what it’s like to build on it before the rough edges get sanded down.

Then there’s the Portable Text content model. Content stored as structured JSON, not HTML strings, not markdown-that-gets-compiled-to-HTML. I’m perfectly comfortable writing markdown and I don’t strictly need a CMS for a personal blog. But JSON is the lingua franca of the agentic era. Every MCP server speaks it. Every AI tool chain consumes it natively. Markdown works fine for human authoring, but the moment an agent needs to read, modify, or generate your content, it’s parsing a format that was designed for human eyes, not programmatic manipulation. Portable Text sidesteps that entirely. Your content is structured data from the start, which means it’s ready for whatever comes next, whether that’s an AI agent, a mobile app, or a frontend that doesn’t exist yet. After years of markdown-everything, this felt like a genuine opportunity to explore the alternative.

And honestly, I just want to see where Cloudflare is going with this. They acquired Astro in January. They shipped EmDash three months later with Matt Kane from the Astro core team leading engineering. When the company that runs a significant chunk of the internet’s infrastructure calls something the “spiritual successor to WordPress,” I want to be close enough to have an informed opinion about whether that’s ambitious or delusional. The only way to get that opinion is to build on it.

Why Astro

Astro is the comfortable part. If EmDash is the risky bet, Astro is the reason I can afford to make it.

Something about Astro’s mental model fits how I think about the web. HTML is the default. JavaScript is opt-in, per component. Content is a first-class concern, not an afterthought bolted onto a JavaScript application framework. Pages are files. It feels like the web is supposed to feel. A page loads and it’s just there, not a white screen waiting for a bundle to hydrate a div.

That said, I’m not running the safe version. I’m on Astro 6 with the experimental Rust compiler and queued rendering turned on, both explicitly labeled “not ready for production.” I turned them on because the stakes are low and I want practice dealing with the rough stuff. When experimental features break, the error messages are worse, the Stack Overflow answers don’t exist yet, and you end up reading framework source code. That’s uncomfortable. It’s also the fastest way to learn how a tool actually works, rather than how its tutorial works.

Why Cloudflare Pages

It’s cheap, it’s fast, and it pairs naturally with EmDash.

The “cheap” part matters more than I’d like to admit. The kid takes tap dancing lessons, and everyone in my house insists on eating. The economics of side projects are not theoretical. Cloudflare Pages’ free tier is generous, Workers pricing is pay-per-request, D1 is practically free at hobby scale. I’m running a blog with a full CMS, a database, and edge deployment for roughly the cost of a mediocre cup of coffee per month.

The Cloudflare bet also makes more sense when you’re already committed to EmDash and Astro 6’s workerd integration. The dev server runs your actual production runtime locally. Workers bindings, D1, all of it. The gap between localhost and production is smaller than it’s ever been.

Why TailwindCSS

Because it works and I know it. Tailwind is the load-bearing wall of normalcy in a stack held together with beta software and good intentions. Sometimes the right choice is the boring one.

The Philosophy of Poor Decisions

Most of the code I write professionally is reasonable. It should be. Clients are paying for it, and reasonable decisions are part of the service. The technologies are proven, the architectures are documented, the failure modes are understood.

But there’s real value in having a place where you’re allowed to be unreasonable. Where you can pick a tool because you’re curious, not because it’s safe. Where “I wanted to see what would happen” is a valid architectural justification. Where the only person who suffers when an experimental compiler flag causes a weird rendering bug at 11 PM is you.

sahd.dev is that place. Every problem I hit is a blog post. Every workaround is something I’ll know when the tools mature. Every “well, that didn’t work” is a future conversation where I can say “actually, I tried that. Here’s what I found.”

Framework — Astro 6 (w/ experimental flags) — Medium: stable core, experimental edges

CMS — EmDash v0.1.0 — High: beta, no ecosystem, building anyway

Styling — TailwindCSS — Low: boring, reliable, correct

Hosting — Cloudflare Pages + Workers + D1 — Low: cheap, fast, natural pairing

Compiler — Experimental Rust compiler — High: explicitly “not production ready”

Total monthly cost: less than the kid’s tap shoes. Significantly less.

Poor decisions, made deliberately, in a safe environment, documented publicly. That’s the service.

If you’ve used EmDash, or if you’re building on Astro 6’s experimental features, I’d like to hear about it. What broke? What surprised you? What are you running that the documentation told you not to? Find me at @sahddev.bsky.social on Bluesky.