Rebuild Notes: Astro + Bun + Cloudflare Workers

June 20, 2026 meta · astro · cloudflare

I rebuilt this site over the weekend. It was on Next.js 15 + OpenNext, deployed to Cloudflare, and had been a placeholder for most of a year. Three project pages that said “Details coming soon!”, a dead-link menu item, a README that was the OpenNext boilerplate. The technical debt was less interesting than the realization that I’d been deferring all the work that wasn’t “make it work once”: the actual writing, the project pages, the polish.

So I tore it down. The new stack:

What surprised me

Astro 6 + Cloudflare is a first-party combo now. Cloudflare acquired Astro in January 2026, and the adapter writes directly to the Workers runtime. The deploy is one wrangler deploy after astro build. I expected more glue. There wasn’t any.

Per-endpoint prerender = false actually works in a static-output site. The whole site is statically built except for /api/*, which is SSR. The adapter handles the split via _routes.json. The static pages bypass the worker entirely. Only API requests hit it. I was bracing for an output: "server" flip and a longer build. Didn’t need it.

The “static-first with islands” pattern is the right default for a content site. Every page except the home ships zero JavaScript. The home ships 204KB total, but 184KB of that is the React + Astro client runtime, not my code. The actual island bundles are 4KB each. I haven’t tried to optimize the React runtime. For a personal site, it doesn’t matter, and 184KB on a single home page is fine.

VT323 self-hosted from npm via @fontsource/vt323. The previous site was using next/font/google which would have broken in the Astro build anyway, but I was happy to drop the Google Fonts request entirely. The font now ships from the same origin. No third-party DNS lookup, no privacy concern.

Bun + Astro + Cloudflare is slightly weird in dev. astro dev uses Node (or Bun’s Vite) for the dev server, but the API endpoints run through astro, not through wrangler dev. So when I tested the KV increment locally, I was actually running against Astro’s local API simulation, not real Cloudflare. Fine for a smoke test. For anything that needs the real bindings (D1 migrations, R2), use wrangler dev or wrangler --remote.

What’s still rough

Takeaway

The boring conclusion: the rewrite was worth it because it removed the accumulated “I’ll get to it” tax. The new stack isn’t dramatically better than the old one in any single dimension. It’s just lower-friction to maintain, which means I’m more likely to actually maintain it.

Whether the site stays maintained is a question for future me. This post is the receipt that at least the rebuild was real.