Skip to content

How this site is built

This site reflects how I think about technology decisions: choose the right tool, keep things simple, and build with care from the start.


Stack

The site is built with Astro, a static-first web framework. I initially reached for SvelteKit, which I've used and enjoyed in the past, but realized it was more framework than this site needed. SvelteKit is designed for web applications. Astro is designed for websites. For a site that's entirely static content with no client-side interactivity, Astro's zero-JavaScript-by-default philosophy is the right architectural choice.

Styling is handled by Tailwind CSS. I've spent enough years building utility classes by hand on various projects to appreciate having a standardized system. Tailwind's explicitness is its strength: you can read the markup and understand the layout without hunting through stylesheets. The typography is set in Instrument Serif and DM Sans, self-hosted via Fontsource.


Infrastructure

The site is deployed to Cloudflare Workers with DNS and CDN handled by Cloudflare as well. I've used Cloudflare professionally for over a decade, but Workers was a new area for me. Even for a site that will never need to operate at scale, the learning opportunity was worth it.

TLS is automatic via Cloudflare. I was an early advocate for full-site HTTPS back when certificates were expensive and EV certs cost a small fortune. Today, encryption is the default. That's progress.

Analytics are provided by Cloudflare Web Analytics, which is cookie-free and collects no personally identifiable information. This site is designed to be compliant with GDPR, CCPA/CPRA, and WCAG from the ground up, not bolted on after the fact. Compliance is a design decision, not a remediation project.


Development practices

The project includes a devcontainer configuration, making the development environment completely reproducible. The container is based on Ubuntu with toolchains managed by asdf, and includes the Fish shell with Starship prompt. Everything needed to work on the project is there from a cold start. No "works on my machine" surprises. Just Docker and an IDE.

I've moved to devcontainers for every project I maintain. Each one is sandboxed with its own runtime versions and tooling, ephemeral by design, and rebuildable to a known state in seconds. After years of manually managing SDK and toolchain installations and dealing with the inevitable drift and breakage that comes with it, the predictability is worth every bit of the initial setup.

Code quality is enforced through Prettier, ESLint, Stylelint, and markdownlint, with Lefthook running checks before each commit. The CI pipeline on GitHub Actions runs the full suite (formatting, linting, accessibility checks, and builds) using reusable workflows to keep things consistent across my projects. Deployment to Cloudflare Workers is CI-gated: nothing ships unless every check passes.

Renovate manages dependency updates automatically, opening pull requests that run through the full pipeline before auto-merging. Major version bumps require manual review, but everything else stays current without my intervention. Renovate even manages Dockerfile base images and runtime versions. I contributed the Gleam language support to Renovate myself, so it's a project I care about.


Accessibility

The site targets WCAG 2.2 AA compliance. This includes semantic HTML structure, proper heading hierarchy, keyboard navigation with a skip-to-content link, sufficient color contrast ratios, and screen reader considerations throughout. Accessibility is tested continuously using automated tooling integrated into the development workflow.

Building accessibility in from the start costs almost nothing compared to retrofitting it later. And it's the right thing to do.


Open source

The source code for this site is publicly available on GitHub (opens in new tab) under the Apache 2.0 license. It's not a library or a tool anyone would use directly, but making the source available is in the spirit of open source. Others are free to read, learn from, and borrow from it.

Developing in public also holds me to a higher standard. When the source is visible, shortcuts become harder to justify and every decision gets a little more thought. I've yet to meet an engineer who isn't at least slightly embarrassed by their own code. But that self-awareness is part of what drives us to keep improving.