Building this blog
I’ve always loved Benji Taylor’s personal site. My old minimal page was based on his, before he had a blog. And then when he added to it, I wanted to rebuild everything from scratch.
You probably don’t need a blog — I’m not sure anyone does.1 People don’t even finish YouTube videos anymore. But if you’re going to have one, it may as well look like this.
Where the idea came from
This site is based on two others.
The design is from Benji Taylor’s site. I don’t really know anything about design, and he knows everything. And I couldn’t afford a designer,2 but I certainly can follow a spec.
The architecture comes from Guillermo Rauch’s blog. Everything about how this is set up comes from his blog: the open source GitHub repo, the MDX files that are their own routes, and the one line in a JSON registry driving the index. No CMS, no database, no frontmatter parser.
So the site is a combo of the two: Benji’s aesthetic on Guillermo’s skeleton.
How it works
Each post lives at app/(articles)/<slug>/page.mdx and ships at the root path (this one is just /building-this-blog). There’s no CMS and no frontmatter parser, because a post is a file and the file is the route:
import { Counter } from "./counter";
export const metadata = { title: "Hello" };
This is a whole post. The button below is a React component,
imported one line up and dropped straight into the prose:
<Counter />A single posts.json registry holds each post’s slug, title, and date; the homepage index and the shared article layout both read from it, so the index and the page header can never drift out of sync. Code is highlighted at build time with rehype-pretty-code, every element a post might reach for is already styled, and the whole thing prerenders to static HTML.
Posts that do things
Because a post is a real React route, the component it imports is really running. Here’s the one from the file above, live:
That’s kind of the main trick.3 A post about a gesture can contain the gesture. A post about an animation can play the animation. There’s no CMS to decide what I can and can’t use. So the whole thing is an escape hatch.
The fun parts
I tried to get as many of the details right from Benji’s site, because they’re what make it feel nice.
For instance, the margin notes are my actual handwriting. I used Calligraphr to make a custom font from a photo in my notebook, and loaded it in with next/font.
How I created my own font for the margin notes.
The bracket used in the margin notes is drawn with rough.js and rough-notation. It sketches a slightly wobbly line, and redraws it a bit differently each time. And it waits until the note scrolls into view to run the animation.
To get a nice highlighter effect, I combine a few randomized gradients, paddings, and tilts. And they’re all seeded by the text itself. That way, it pools at the edges naturally and never changes between renders.
And finally, there’s a very nice .
Footnotes
-
Except maybe Sam Altman and Paul Graham. ↩
-
The Consumer Price Index is up about a fifth since 2020. Designer rates are up even more. ↩
-
The counter above is an ordinary client component co-located in this post’s folder. You don’t need a plugin or shortcode. It animates with Framer Motion. ↩