Personal site. Portfolio, bookshelf, and a place to point people when they ask "so what do you do?"
Built with Astro 6, Tailwind CSS 4, and TypeScript. Static output, zero runtime, fast everywhere.
Astro generates everything at build time. Pages pull from TypeScript data modules, render through a shared layout with section components, and ship as plain HTML/CSS/JS. The OG image pipeline runs in parallel — Satori renders JSX to SVG, resvg-js converts to PNG, one image per route.
- Astro 6 — file-based routing, static site generation
- Tailwind CSS 4 —
@themetokens inglobal.css, no config file - TypeScript — data modules and the OG image pipeline
- Satori + resvg-js — build-time Open Graph images
- Slidev — talk slides built from Markdown source in
slides/ - PostHog — analytics (optional, needs env vars)
src/
├── assets/fonts/ TTFs for OG image rendering (Satori needs local fonts)
├── components/ Astro section components
│ ├── Hero.astro
│ ├── About.astro
│ ├── Projects.astro
│ ├── Experience.astro
│ ├── Writing.astro
│ ├── Contact.astro
│ └── ...
├── data/ TypeScript data modules
│ ├── projects.ts
│ ├── books.ts
│ └── analytics.ts
├── layouts/
│ └── Base.astro HTML shell, meta, nav, OG tags
├── pages/
│ ├── index.astro Main portfolio page
│ ├── bookshelf/ Reading list with per-book pages
│ └── og/[...slug].png.ts OG image endpoint (runs at build)
└── styles/
└── global.css Tailwind v4 @theme tokens
Requires Node.js >= 22.12.0 and pnpm.
git clone https://github.com/samuelabc/personal-site.git
cd personal-site
pnpm installpnpm dev # dev server at localhost:4321
pnpm build # build slides + static site to dist/
pnpm preview # preview the production build
pnpm build:slides:pdf # export slides to PDF (local only, needs Chromium)Slides in slides/ are built automatically during pnpm build and output to public/talks/durable-execution/. The built slides are gitignored.
PDF export is local-only. Slidev uses Playwright to launch a headless Chromium browser for PDF generation. Cloudflare Pages (and most CI environments) don't have Chromium installed, so download: true is intentionally omitted from the slides frontmatter — setting it would make slidev build try to launch Playwright and fail in CI. To generate a PDF locally, run pnpm build:slides:pdf — this requires playwright-chromium (listed as a devDependency in slides/package.json) and will prompt you to run pnpm exec playwright install chromium on first use.
cp .env.example .envPostHog analytics is optional. The site runs fine without it.
Hosted on Cloudflare Pages. Builds to static HTML in dist/.
