Skip to content
back to portfolio

Open-source and personal projects2026

kevinmurphywebdev.com — personal site + portfolio + resume

Personal site, portfolio, blog, and live resume — Next.js 16 App Router with Server Components, MDX-driven case studies and blog posts, programmatic resume rendered from a single JSON source of truth, and a per-build PDF export pipeline (Puppeteer over the rendered /resume route) so the downloadable PDF can never drift from the live site. Lighthouse 95+ across all four scores; deployed on Vercel.

Author · designer · engineerNext.js 16React 19TypeScriptTailwind v4MDXVercel

Live site: kevinmurphywebdev.com

Source: github.com/midimurphdesigns (private — happy to share the brand-system + ADR docs on request)

The site you're reading. Built by hand on Next.js 16's App Router with React Server Components, Tailwind v4's CSS-first design tokens, MDX-driven content, and a programmatic resume rendered from a single JSON source of truth. 95+ Lighthouse on desktop across all four scores. Per-build PDF export of the resume so the downloadable file can never drift from the live page.

How it's built

Server Components by default — "use client" only appears where it's required (cursor, smooth scroll, demo subdomains). Tailwind v4's CSS-first config sits in app/globals.css via @theme, so design tokens are the source of truth for both runtime CSS and tooling that needs to read them. No tailwind.config.js. Three-tier type hierarchy locked in an ADR (Migra italic for display ≥32px, Space Grotesk for body, Geist Mono for metadata). Single cyan accent on near-black canvas; no glass, no gradient mesh, no card grid. The resume page reads from one resume.json file; a postbuild Puppeteer hook re-renders the live /resume route as a PDF on every Vercel deploy, so the download is always the live page.

Artifacts worth reading

The trade-offs

Hand-building every primitive — KMLogo, Cursor, Hero, Header, the resume renderer, the OG-image route — takes longer than dropping a template. The trade is that nothing on the site is a vendor's idea of how it should look. It's a place I can iterate on without fighting somebody else's defaults.