All projects
Solo developer Jul 2026

Portfolio Site Template

The Astro template this very site runs on. One typed config file drives every word of content, it costs $0 to host, and a friend could make it theirs without touching a component.

  • Astro
  • Tailwind CSS
  • TypeScript
  • Cloudflare Pages
The portfolio homepage hero in dark mode: accent glow, proof-chip tagline, and headshot

Problem

Good developer portfolios are surprisingly hard to keep: they rot, they cost money to host, and personalizing someone else’s template usually means digging through markup. I wanted a portfolio that costs $0, survives years of neglect, and that a friend could make their own without touching code. I also wanted the code to stay private while the site stays public.

What I built

The site you’re reading, so you’re looking at the live demo right now. It’s a static Astro site that ships zero JavaScript by default, with every personal string driven by a single typed config file and a content folder.

  • One file to personalize: site.config.ts holds the name, headline, bio, links, skills, accent color, and feature flags. No personal strings live in any component, so a fork becomes someone else’s site by editing one file.
  • Content collections: adding a project means dropping a Markdown file in a folder. Zod schemas validate every field (including images) at build time, so a typo fails the build instead of the site, and an in-repo _example.md documents every field.
  • Free hosting, private code: Cloudflare Pages builds straight from a private repo on every push, while GitHub Actions runs type-checking and a full production build as CI. The repo stays private; the site stays public; the bill stays $0.

How it works

  • Astro (static output) for content-first pages and a tiny payload. The interactive bits (theme toggle, lightbox, mobile menu, copy-email fallback) are small islands of vanilla script.
  • Tailwind CSS v4 theme tokens: the entire site (buttons, links, focus rings, glows) re-skins from a single accent preset in the config, with eight presets built in.
  • TypeScript (strict) across the config, components, and content schemas.
  • Progressive enhancement everywhere: dark mode with no flash of the wrong theme, a keyboard-navigable lightbox, and a mobile menu built on <details>, so every page keeps working with JavaScript disabled.
  • Self-hosted variable fonts, astro:assets image optimization, canonical URLs, Open Graph tags, JSON-LD, a sitemap, and a custom 404.

Impact / results

  • Deployed as my real portfolio. The pages you’re browsing are the template running unmodified.
  • Fast by construction: optimized images, self-hosted fonts, and no render-blocking JavaScript.
  • Honest sustainability: no servers, no build minutes to pay for, no analytics by default (privacy-friendly options are one config line away).
  • Reusable: a fork needs edits to exactly one config file, plus content and images, to become someone else’s site.

What I’d do next

  • Generated Open Graph images per project.
  • A public template repo with a one-click “Deploy to Cloudflare Pages” setup guide.
  • A light/heavy content-density option for people with more (or fewer) projects.

Gallery