DaftForge — home

Forging a portfolio on Astro + Cloudflare


This portfolio is intentionally simple. Astro builds the home page, tool pages, and Notes posts into static HTML at deploy time. Cloudflare then serves those files from the edge. Most visits therefore do not need a server, database query, or application code to run before the page appears.

There is one exception: /api/contact. A contact form has work to do. It has to validate the submission, send the message, and tell the visitor whether that worked. That route runs on the same Cloudflare Worker as the site. Everything else is a static file, which is exactly what it should be.

The content lives in Astro collections rather than a database. Tools and Notes are typed Markdown files in src/content/, checked against a Zod schema during the build. If a post is missing a title or has an invalid pubDate, the build fails before the site goes live. That is a better time to find an error than when someone is trying to read the page.

It also keeps publishing boring in the useful sense: write a Markdown file, commit it, deploy it. No schema migration, connection pool, or admin panel is needed for a portfolio that changes when there is genuinely something worth adding.

Static-first is a practical choice as much as a technical one. Static assets are inexpensive to host and fast to serve. There is no application server to patch, no database to back up, and fewer moving parts to troubleshoot when I would rather be working on the next tool. The site is small on purpose, but the approach scales comfortably with the kind of work it needs to show.

Keeping the contact route with the rest of the site avoids a second backend for one narrow job. It is deliberately small and single-purpose, which makes it easier to understand, test, and maintain. If the site later earns another dynamic feature, it has to justify the extra complexity instead of sneaking in by default.

The same principle applies to the type. Space Grotesk, Inter, and JetBrains Mono are bundled through Fontsource rather than fetched from a third-party font CDN. That removes an extra request and one more outside dependency from the critical path. It is not a dramatic optimization. It is simply the same habit applied consistently: ship what the page needs, keep the runtime quiet, and make the exceptions earn their place.