Why this site runs on Astro and Cloudflare Workers
This post documents why this site is built the way it is, and doubles as a demonstration of the Markdown features available to every post.
The requirements
A personal developer blog does not need much:
- Fast page loads with no client-side framework
- Content written in plain Markdown files
- Version control for posts, the same as for code
- Free hosting with a simple deploy step
- No database, no server, no maintenance
Why Astro
Astro ships zero JavaScript by default. Every page
on this site is plain HTML and CSS; the only scripts are a tiny inline theme
toggle and a decorative three.js scene on the home page. Content lives in a
content collection,
so every post’s frontmatter is validated at build time — a typo like
publishd fails the build instead of silently breaking the page.
The frontmatter schema is enforced with zod via src/content.config.ts:
const blog = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
schema: z.object({
title: z.string().min(1),
publishedAt: z.coerce.date(),
draft: z.boolean().default(false),
// ...
}),
});
Why Cloudflare Workers
- Static assets are served free from Cloudflare’s edge network, close to every reader.
- Deployment is one command —
wrangler deployuploads thedist/folder and the site is live seconds later. - The custom 404 page just works, and a custom domain is a one-click setting away.
The whole configuration fits in a few lines of wrangler.jsonc:
{
"name": "joatandev",
"compatibility_date": "2026-07-17",
"assets": {
"directory": "./dist",
"not_found_handling": "404-page"
}
}
What a deploy looks like
npm run build
npx wrangler deploy
That is the entire release process.