cat ~/writing/rebuilding-zj-rs-markdown-in-html-out.md
Rebuilding zj.rs: Markdown In, HTML Out
In August 2024 I wrote that it was time to update my homepage. I picked Gatsby with a ready-made theme by LekoArts, and wrote that I would add features gradually. I didn't.
Two years later the site was still that same theme. Its lockfile had grown to 21,913 lines, and GitHub listed 112 Dependabot alerts for a site that shows ten blog posts. So I started over.
Markdown in, HTML out
The new site has no framework.
Posts are plain markdown files, and about 730 lines of TypeScript turn them into static HTML.
The build highlights code with Shiki, converts images to webp with sharp, and minifies the CSS and JavaScript with esbuild.
A full build takes about a second.
The project now has 9 dependencies, and all of them run only at build time. Your browser gets the HTML, one 3.8 KB stylesheet and one 3.9 KB script (gzipped).
A terminal for a homepage
As a developer, I wanted the site to look like a terminal. Everything is set in JetBrains Mono, in shades of black and white.
Inspired by ascii.rest, which builds whole pages out of plain text, and by the dithered speaker photos on Supabase Select.
One accent colour marks the small details, like the prompt and the cursor. You can pick your own from the dot in the header. All six colours are tuned to stay readable on both the light and the dark theme.
Dithered images
Screenshots in my posts are shown as 1-bit images, with the dots drawn in the text colour. Hover over one, or tap it on a phone, and the full-colour image fades in.
The dithering happens in your browser, in a background worker, so it doesn't slow the page down. At the bottom of any post with images you can switch between Atkinson, Floyd–Steinberg and Bayer dithering, and pick the dot size. The site remembers your choice.
A 404 worth landing on
Broken links happen, so the 404 page plays a short shell session.
It tries to cd into the missing path, fails, and then greps my posts for words from the URL.
If one matches, you get a link to the post you were probably looking for.
The numbers
On the live site, Lighthouse scores the home page and the posts I tested at 100 for performance, SEO and best practices. Blocking time is close to zero. The images in my posts went from 5.5 MB of PNG files to 380 KB of webp. GitHub now shows zero Dependabot alerts.