Skip to main content

This site

The stack

Built to be fast, accessible, and easy to maintain — with a single content pipeline for articles, RSS, and listings, and automated checks in CI. No dependency theatre.

Framework

Astro ships minimal JavaScript by default — HTML is rendered at build time and only the scripts that actually need the browser are sent. The view transitions client router (opens in new tab) powers in-page navigation without a heavy SPA. The content collections API drives all writing: MDX files, the /writing/ index, article URLs, and the RSS feed share one schema (Zod) so typos in frontmatter fail at build time, not in production.

Language

TypeScript — strict mode

Strict TypeScript throughout. Every component, page, and i18n object is typed. Catching shape mismatches at build time rather than runtime is especially useful when content schemas evolve — a missing field breaks the build, not a production page.

Content

MDX + Astro Content Collections

Articles live as MDX under src/content/writing/. The writing page, RSS (/rss.xml), and each post URL are all generated from that collection — no duplicate post lists in copy files. Frontmatter includes title, description, date, mediumUrl, and category. MDX supports astro:assets for images and small components such as pull quotes.

Styling

Vanilla CSS — scoped + global tokens

No CSS framework. A token system in :root covers colour, spacing, typography, and radius. Component styles are scoped with Astro's built-in style scoping. Fluid typography uses clamp() throughout — font sizes scale smoothly between breakpoints with no media queries. Animations respect prefers-reduced-motion site-wide.

Typography

Syne · Outfit · DM Mono Google Fonts ↗ (opens in new tab)

Three typefaces with distinct roles: Syne for display headings, Outfit for body text, and DM Mono for labels, metadata, and inline code. Fonts are self-hosted as WOFF2 subsets in public/fonts/ with font-display: swap and preload for the primary Latin files — no third-party font request on load.

Deployment

Static output

The site is fully static — Astro pre-renders every page to plain HTML at build time. No server, no runtime, no database. Deployable to any CDN or static host.

SEO & metadata

JSON-LD · Open Graph · Sitemap

Every page has structured data (Schema.org Person, WebSite, Article where relevant), Open Graph / Twitter meta, and a generated sitemap via @astrojs/sitemap. Canonical URLs use a single site origin, and Astro is configured for trailing slashes on routes so URLs stay consistent.

Dependencies

3 production dependencies

Production: astro, @astrojs/mdx, @astrojs/sitemap, and @astrojs/rss. No UI framework, no animation library — the marquee, hero glow, TOC spy, and theme toggle are plain TypeScript.

Quality & CI

Tests, axe, GitHub Actions Repository ↗ (opens in new tab)

Vitest covers small shared helpers. Playwright serves the production build and runs Deque axe-core against core templates in light and dark themes. GitHub Actions runs astro check, unit tests, and Playwright on pull requests and on main; failed e2e runs attach an HTML report. Local parity: npm run verify.

Tooling uses Node 22 in CI; package.json enforces engines.node >= 22.

Source

The full source is on GitHub (opens in new tab).

Last updated: April 2026