Skip to main content

Blog

My thoughts exploring design systems, product design, and front-end development.

Over-engineering my personal website

This website is doing A LOT. Too much for a personal website.

I'll say that up front so the rest of this reads as a confession, not a brag. A personal site needs a few pages, a way to get in touch, and somewhere to show your work. Mine has turned into something closer to a small product. It has its own design system, its own build pipeline, and a set of AI agents that work on it while I sleep. I built all of that on purpose, and almost none of it is necessary.

So here's what's actually running.

A real design system

My design system backs the site, my résumé (PDF), and a slide deck. On the design side that's Figma variables and components. On the code side it's design tokens and React components. The two stay in sync instead of being redrawn by hand.

Design tokens with a pipeline

A single source-of-truth file holds the design tokens, and a build step compiles them into themed CSS for light and dark. A GitHub Action rebuilds the CSS on every change and fails the build if it ever drifts from the source, so the tokens can't quietly fall out of sync. An AI skill is wired into this too, so I can pull token changes out of Figma or push corrected values back without hand-editing either side.

49 components, each with a contract

The site has 49 components. Each component ships with the same contracts, in the same change that introduces it: a Storybook story, a Code Connect mapping back to its Figma symbol, and an automated accessibility test. The rules live in a file the AI reads before it writes anything, so a generated component shows up already matching the conventions I'd have used myself.

A résumé that builds itself

My résumé is a page on the site, styled from the same tokens as everything else. A script renders it to a PDF, and CI regenerates that PDF whenever something that affects it changes: the print layout, the résumé data, the tokens. The copy a visitor downloads is always current, and I never export it by hand.

AI baked into the workflow

Underneath all of this is the tooling that makes it sustainable: custom skills, persistent memory, and repo-specific instructions. This is the layer that lets me hand off real work and get back something I'd have written myself, instead of something generic I then have to rewrite.

An AI "circadian rhythm"

The most over-engineered piece is a daily build loop. Agents can design and code the site during off-hours, then hand me a briefing in the morning. They open pull requests. They never merge. I'm the only gate. Within limits I set, the site improves itself overnight, and during the day the same agents work alongside me on whatever I'm actually building.

So why do I need all this?

Truly, I don't. But that's the point. This site is a testing ground, somewhere to learn and stress-test tools and ideas I might not get to touch at a day job. The stakes are low, the surface area is mine, and the only person who files a bug when I break it is me.

Going head first into new technology I find interesting is also the reason I've never specialized strictly in design or strictly in engineering. Design systems is where those two halves meet, and it's where I'm happiest.

The part I want to be precise about is the AI, because it's easy to misread. Most of this tooling maintains itself, largely through Claude. A system this size would otherwise be a heavy maintenance load on its own, and that kind of load is what quietly kills a side project. This is less "vibe coding" and more just being more productive. I'm not pasting in a prompt and shipping whatever comes back. I reach for it because it lets me build more than I'd otherwise have time for.

To be continued

I plan to write more detailed posts about some of the systems running behind the scenes. To be honest, most of them are still works in progress, and I want to iron them out fully before I write them up.