Every so often, I describe what I do to make this site a reality. For the four of you who like to watch me gaze at my navel, I have good news: today is one of those days. For the rest of you, I’m sorry. It’s one of those days. You can move on. I won’t be offended.

Okay, here goes.


I use a 14” M1 MacBook Pro with a large external monitor to compose all my essays. I love this machine. Years ago, my Windows laptop died and I decided to see if life was better on the other side. I’ve come to like MacOS, after some initial frustrations, and now I have a hard time imagining going back.

I write my essays in hand-crafted HTML using Webstorm. The files are served using a custom content management engine (CME) I originally wrote for my Let’s Code JavaScript screencast. It’s a polyglot engine, so I could theoretically use other markup languages, such as Pug, Markdown, or AsciiDoc, but I’m used to HTML. I do have a very hacked-together parser for AsciiDoc that I wrote to support my book, which is written in AsciiDoc, but I use HTML everywhere else.

Everything required to make the site go, including all the content, is stored as static files in a git repository. I run my CME locally for testing, then push to my web host when I’m ready to go live. I’ve got a really nice local build script that validates my changes and restarts the server faster than I can switch windows.

I’m paranoid about backups and revision control. There’s decades of work here. That’s why my essays are written in a text editor and stored in git. Most blogging engines save your work in the cloud. Easy, but not fault tolerant. I’ve been writing for nearly two decades and plan to continue writing for several more. My stuff has to be easily scripted, version-controlled, backed up, and trivial to deploy to another web host when (not if) my host goes under... which it already has. Twice.

My site is backed up many times over. First, in the git repo on my laptop. Second, in a copy of the git repo on my web host. The computer itself is backed up to two redundant drives with Time Machine every hour. I also make a bootable whole-disk backup using SuperDuper! every night. Once per quarter, I rotate one of my backup drives to an off-site location. I also continuously backup to the cloud using Backblaze.

Yeah... I might be a bit paranoid. But in 20 years, I’ve never lost data... at least, not that I couldn’t recover.


The site was originally designed in 2005. For 15 years, it had a very... “classic” look, and it didn’t work well on mobile. In 2020, I finally redesigned the site. I’m very happy with it, and particularly proud of its dark mode support and custom print styling.1

1Try it out! Click the “Print” button at the top of this page, or just tell your browser to print the page.

I’m not much of a graphic designer, so I did what great artists do: I stole whatever I could. Dave Liepmann’s Tufte CSS, based on the work of Edward Tufte, was my principal inspiration. The home page was inspired by Michael “GeePaw” Hill’s website,2 although he’s since changed his design.

2GeePaw Hill is super smart and thoughtful about Agile engineering practices. Go read his stuff.

The site’s fairly monochromatic, but there’s bits of color here and there. The colors are based on my Let’s Code JavaScript site, which was professionally designed by the talented folks at Primate.

This is a JavaScript-free site, almost, which is a bit ironic considering that I had a subscription screencast about JavaScript for many years. I guess you could say I know it well enough to know when not to use it. The one exception is syntax highlighting, which is provided by Prism. It’s all progressive, though, so the site works fine if JavaScript is disabled.

Icons3 are in SVG, which I want to love, and probably will someday. After they make it better. I purchased my icons from The Noun Project, except for the Mastodon logo, which I got from their brand toolkit. I also use emojis as icons4 in a few spots, mostly because they’re so much easier to work with.

3 Subscribe icon Mastodon icon Search icon Print icon

4 ⭐️ 📖 🎙

Fonts come from Adobe. I’m using Utopia for my main serif font, Cronos for my sans serif buttons and some links, and good old Courier for monospace—or Menlo, if you happen to have it installed.

Finally, lots of elbow grease got me to the result I have today. MDN, the Mozilla Developer Network, was invaluable for figuring out the style sheet. CSS has improved a lot since 2005, and I think I might even... like it? Well, almost.

Nearly all of the original design has been wiped away, but one I did keep one of my favorite aspects: printed URLs. I learned that from Eric Meyer’s “Going to Print” article.


The site is hosted by Heroku and runs on a custom content management engine I wrote in Node.js. Logging is handled by Papertrail, which also sends me email and text message alerts when things go wrong. I use Pingdom as a backup alerting system. TierraNet makes sure that my domains point to the right place. I use DuckDuckGo for my site search and Google Groups for update emails.

Also, I’ve finally dumped Google Analytics. Woot! No cookies or tracking of any sort, in fact, unless you visit a page with an embedded YouTube video. YouTube’s behavior is out of my control, unfortunately.

The combination of custom source code and outside services gives me total control over the code behind the site while outsourcing a lot of the complexities of modern software stacks. It’s a nice tradeoff that allows me to focus my attention on more important things. The code is very well tested, so it almost never fails. Because there’s no database and minimal service dependencies, my uptime is the same as Heroku’s, and requires no effort from me.

Having custom source code has allowed me to tune the site into a well-oiled machine. I don’t get a ton of traffic—I’m lucky to average 15 requests per second—but a single low-end Heroku dyno is all I’ve needed to handle everything the Internet has thrown at me. Typical service time is around 5ms, and I’m confident enough in its performance that I start getting warning emails if responses take longer than 100ms.


In the very beginning, the site was rendered by a very simple static site generator I wrote in Ruby. But for 15 years, from February 2005 to July 2020, the site was rendered by the ultra-minimalistic Blosxom. That’s when I started blogging in earnest; you can see my very first entry here.

Back in the day, Blosxom was the only blogging software I could find that actually allowed me to store entries locally, in files that I could back up and put in version control, rather than on a database on the server. (Nowadays, of course, static site generators are a dime a dozen.)

Blosxom ran on Perl 5 in Apache on NearlyFreeSpeech.NET. It did the job, but my volume of content caused performance problems, and it had a lot of idiosyncracies. It was low maintenance, but also constrained what I could do. My new codebase is even lower maintenance, and more powerful. I’m happy to have moved on.

Colophonem adidi.

If you liked this entry, check out my best writing and presentations, and consider subscribing to updates by email or RSS.