Building this site with Claude Code
My old site was fine. Functional, reasonably fast, built on Ghost, which I actually quite like. But it felt like a template—because it mostly was one. I’d spent a lot of painful hours tinkering with it and the result was decent but full of compromises and didn’t really showcase the craft I’d hoped to put into my own little corner of the internet.
So I rebuilt it from scratch with Claude Code, Anthropic’s command-line AI assistant.
I should be clear (and if you’ve read anything else I’ve written, this won’t surprise you): I am not an engineer. The way I used Claude Code was closer to having a very fast, very patient design partner who also happens to write CSS. I’d say “that feels heavy” and watch it get lighter. I’d ask “what are three ways to solve this?” and see them all in minutes. The conversation was the design tool.
What started as a January weekend project turned into… well. The git log shows 304 commits. About 190 of those are features—new pages, new systems, obsessive typographic details. The rest are content syncs from Obsidian, which is its own story.
Here’s what happened.
Starting with typography
Most sites start with layout or content. Me being me, I started with fonts. Of course I did.
I thought I wanted a serif for body text—something with personality but not too much personality. Claude helped me evaluate options by spinning up multiple versions of the site with different font pairings, all running on different localhost ports. I could flip between them in seconds (which is kind of insane?!). Like flipping through fabric swatches at a tailor, except the whole suit changes.
We tried several combinations:
- Signifier + Söhne—The “OpenAI look.” Too trendy, too expected.
- Signifier + Inter—Safe but boring. Inter is everywhere.
- Signifier + Montreuil—Warmth with a pinch of quirkiness. This was the one.1
Claude asked me if I wanted something discovered or something proven. Easy choice.
Then a subtler problem: my h2 and h3 headings looked too similar and I couldn’t figure out what was bugging me about the page. Claude proposed three solutions—sans-serif h3, muted gray h3, uppercase h3—and we built all three to compare. Uppercase won immediately. It gives h3s a completely different texture, like they’re signposts instead of just smaller text.
This was the whole workflow. No specs. No tickets. I’d just point at something and react. “That’s too much.” “Go back.” “What if it was lighter?” And Claude would do it and I’d react again. You can see how this gets addictive (more on that later).
Paper materiality
Early on I landed on a question that became the rule for every single design decision: would this appear in a well-typeset book?
Yes? Keep it. No? Justify yourself.
And this question led me somewhere weird. The site should feel like a physical object. Not a skeuomorphic fake-paper thing—I don’t mean that—but something with texture and warmth. Something that felt made, like someone actually gave a shit.
We built this in layers. Paper grain texture (warm in light mode, cool in dark). Gentle vignette at the edges. Crop marks in the corners, like a printer’s proof. Even a letterpress-style texture on the type itself. Each layer is barely perceptible on its own. Together they make the page feel warm in a way I still can’t fully articulate—you just notice the absence when it’s off.
The Flexoki color palette was essential here. Warm and papery by default, designed by Steph Ango (the CEO of Obsidian) specifically for reading. With the grain on top, the whole thing feels like it exists somewhere.
The obsessive details
And then I got completely obsessive. This is the part where my wife started giving me looks. Once I had the foundation (typography, color, texture), I started chasing details that most people will never consciously notice. But you feel them—you just don’t know why the page feels good.
Hanging punctuation. Quote marks and bullets that hang into the left margin instead of pushing text inward. Almost every well-set book uses it, but nearly no website does.2 The text edge stays perfectly aligned. Once you see it, you absolutely cannot unsee it, and now every other website will look slightly wrong to you. Sorry.
A breathing favicon. Signifier is a variable-weight font, so I made the favicon gently cycle its weight up and down in your browser tab. It breathes.3 It’s completely pointless and I love it so much.
Margin notes. On longer essays, annotations float in the margin with hand-drawn bracket decorations—rendered with rough.js so they look slightly wobbly, like someone sketched them. I spent an embarrassing amount of time getting the bracket curvature right. On mobile they collapse into footnotes and inline asides, which required its own whole rabbit hole.
Must-read callouts. On the links page, I wanted a way to nudge people toward my favorites. Certain posts get a little handwritten label in the margin (set in Caveat) with an arrow pointing to them—randomly selected from phrases like “don’t skip this” and “read this one.” It’s dumb and delightful.
An accent color picker. Down in the footer, a row of color swatches from the Flexoki palette. Pick one and the whole site’s accent changes.4 First-time visitors get a subtle hint that it’s there.
Drop caps. The first letter of long posts gets a proper drop cap, but only when the first paragraph is tall enough. Otherwise it looks weird—so Claude wrote the logic to measure and decide, which is the kind of fiddly detail that would have taken me forever to figure out on my own.
Each of these took anywhere from one conversation to a couple hours. They added up. The goal was a site that rewards close looking, and I think it does? You tell me.
Content as architecture
The other half was building a content system that matched how I actually think and write. (This part was less sexy but arguably more important.)
I write everything in Obsidian. Notes, drafts, links I want to save, books I’m reading—all in one vault. The site needed to reflect that, so we built six content types:
- Writing—long-form essays (like this one)
- Links—external articles I want to share, often with highlights from Readwise
- Shortlist—curated recommendations organized by category
- Books—my reading log, synced from Book Tracker
- Media—films, TV, and games, synced from Letterboxd, Trakt, and RAWG
- /now—a /now page with an archive of past updates
The publishing pipeline is the part I’m proudest of, engineering-wise (for someone who is not an engineer). I write in Obsidian, it syncs to GitHub, a GitHub Action transforms everything—frontmatter, wikilinks, images—and Vercel deploys. I never touch the website repo. I just write. That’s it.
The feed ties it all together. Writing, links, shortlist entries, all in one stream. It reads like a notebook that happens to be a website, which is exactly what it is.
The tools
So what did this collaboration actually look like? There’s so much vague hand-waving about “building with AI” that doesn’t capture the reality, so let me try to be specific.
Claude Code was the backbone. My collaborator for almost every feature. But the ecosystem around it mattered too. Early on I used Agentation to leave design comments, kind of like Figma for a live site. As things scaled up, Conductor became essential—it runs multiple Claude Code agents in parallel, each in its own git worktree. I could have a dozen PRs in flight simultaneously without them stepping on each other, which is a frankly absurd sentence for someone who learned what a git worktree was like three weeks ago.
I also threw Codex at some of the thorniest issues—complex debugging, code reviews. Playing two AI agents off each other sometimes led to better results. There’s something satisfying about making them compete… Claude builds it, Codex reviews it, and between them I’d get something more thorough than either alone.
The speed is the thing that’s hard to explain to someone who hasn’t experienced it. Not “saves you 20 minutes” fast—“compresses a weekend into an afternoon” fast. All the stuff that used to be friction (looking up CSS properties, remembering Astro’s content collection API, debugging a remark plugin that I’d literally have to learn from scratch every single time) just vanished. I stayed in the creative flow because the implementation kept up with my thinking. When has that ever happened?
And when you can say “show me three options” and see them all in five minutes? You try things you’d never bother attempting if each one cost an hour. Some of my favorite details on this site exist purely because it was cheap to experiment.
Here’s the thing, though. Claude doesn’t have great taste on its own. You have to train it—feed it examples, show it things you like, build up a shared vocabulary over sessions. It can execute on taste beautifully. But the aesthetic judgment was always mine. Every pull quote, every spacing decision, every “actually, let’s not do that” came from me staring at the screen and having a gut reaction. The design sense was human. The implementation speed was superhuman. That combo is wild.
Some things were faster by hand. Quick CSS tweaks where I already knew the property. Writing the actual content (though Claude helped with this very post, lol). Understanding my own janky infrastructure enough to debug deploys.
80/20, roughly. 80% through conversation, 20% by hand. But 100% of the decisions were mine.
The addiction
OK so. It’s addictive. Really addictive.
I’ve skipped workouts. I’ve stayed up past midnight and woken up at 5am, just to keep going. When “I have an idea” and “I can see it working” are separated by minutes instead of hours, your brain just… doesn’t want to stop. It’s the tightest creative feedback loop I’ve ever experienced.
This is mostly a good thing—I haven’t been this excited about making something in a long time, maybe since the early Foursquare days. But the same thing that makes it productive also makes it consuming. I’m still figuring out boundaries. Miranda has opinions about this.
The numbers
Because I find this kind of thing interesting:
- 304 commits since January
- ~190 features (the rest are content syncs)
- 148 pull requests merged
- 6 content types built from scratch
- 3 external data sources integrated (Letterboxd, Trakt, and RAWG)
- 1 design system documented in a 1,500-line spec
- 1 colophon that I’m maybe too proud of
If I’d done this the traditional way—every line of code, every CSS property Googled, every edge case debugged alone—it would have taken months. Maybe longer. Maybe I would have given up, like the last three times I tried to rebuild my site.
Instead, it took weeks. Not even full-time. And I’m not done—there are more ideas in my head than I’ve shipped, which feels like the right problem to have.
What this means
I don’t know what this year has in store. I don’t know what these tools will mean for jobs and design and all the big questions people are understandably anxious about. But what they do right now is lower the barrier to making things. The gap between “I have an idea” and “I have a working thing” is collapsing. And when that gap shrinks, more ideas get tried, more experiments happen, and more weird personal sites exist in the world.
That feels like a good thing to me.
This site exists because I could keep saying “not quite” until it was right. The tool disappeared and what was left was just… making something. Which, at the end of the day, is all I really wanted.
If you’re curious about the design system, the colophon documents everything. If you want to talk about any of this, reach out.
Footnotes
-
Signifier is from Klim Type Foundry. Montreuil is from 205TF. ↩
-
The CSS property
hanging-punctuationdates back to the CSS Text Level 3 spec but only Safari supports it so far. Chrome and Firefox still haven’t shipped it. The typographic convention itself goes back to the Gutenberg Bible—nearly every well-set book since has used it. ↩ -
It also updates to match the accent color you choose—see below. ↩
-
You can also just hit “C” on your keyboard. For fun, try hitting “D” and “F”, too. ↩