Changelog

  • February 8, 2026: Replaced Hugo with a custom static site generator written in Haskell.
  • February 1, 2026: Original site published using Hugo.

This page summarizes how I built this site. I wrote it in a declarative style similar to how I would write an AI prompt. I did not use AI to write the article, but I did use it to create the static site generator powering it.

Philosophy

The website should be clean and fit for purpose. Avoid trendy frameworks like React, which would be overkill here. Any JavaScript should progressively enhance the site (i.e., the site should work without JavaScript, but feel free to optimize if JavaScript is enabled). Do not over-engineer or over-design. The site should be able to host my photos, their metadata, and occasional articles.

Technology

Prefer open source software and plain old HTML and CSS. Minimize JavaScript. Use Python scripts and AI to format and extract metadata from my photos—sharp for generating multiple sizes, ExifTool for aperture and shutter speed data, and AI image understanding for my photosʼ alt-text (TODO: group photos by tags and display metadata in a gallery view).

Image processing pipeline
Original photoProcessingStorageThis sitesharp(resize)ExifToolAI ImageunderstandingR2SQLite 800w.webp1920w.webpmetadataalt text

Store the image metadata in SQLite (use Haskell sqlite-simple package to read). Use D2 for the diagram. Keep text content in Org (.org) format, not Markdown (.md).

Lazily load the thumbnails just outside of the viewport as the user scrolls right. Use the browser’s sessionStorage to remember the scroll position when a user clicks on an image (so they are returned to the same spot in the gallery when clicking the back button).

Deployment and analytics

Host the site on Fly.io. Use Cloudflare for photos (R2 bucket) and CDN to distribute the site. Parse the server-side logs for anonymous analytics; do not use client-side or JavaScript to track visitors.

Design

Land somewhere between motherf—ing website and better motherf—ing website. I.e., give it just enough CSS not to bore the reader but not too much to distract them, either. Add a touch of green in a nod to Hawaii, where I spent some happy years.

Use tasteful system fonts; do not download external ones. The site should load fast and look reasonably good.

Conclusion

The result is a lean website with just enough HTML, CSS, and optional JS to display and organize photos and text. The build pipeline has few dependencies and naturally fits my personal workflow (write in Org, convert to HTML, deploy to any server). And hopefully, the visitor is left inspired to build something unique of their own :)