This website
Since 2006 I’ve had a personal website; though I think I’ve spent 10x as much time writing blog engines or themes as I have writing blog posts! It took me a long time to settle on a platform where I feel I can be productive without having to fiddle around too much with content management.
Technology
This hugo powered website is optimised to load lightning fast using:
- a bs4 + tinycss2 based script to inline CSS/JS + tree-shake CSS and substitute class names
- a selenium script to annotate images below the fold for lazy-loading
- html-minifier (which uses clean-css and UglifyJS)
- optipng, jpegoptim and svgo for originals
- webp images
- no frameworks
- caching rules
- a global CDN + static host
I write articles with neovim, validate with VNU validator, spellcheck with typos, lint with eslint, stylelint and proselint. All automatic, of course.
Theme features
- Audio player
- Video player
- Highly responsive blog cards
- Featured star system
- Hero cover images
- HTML and PDF CV generation
- Image scaling and compression (webp/jpg)
- Gallery support
- Tag intersection system
- First-class code embed highlighting/download support
- Active table of contents
- Fully responsive design, with focus on typography and readability
- Horizontal nav bar, panning support for mobile
- Article GUIDs in RSS feed for persistent IDs
- Nix derivation for reproducible builds
- Automatic slug (url) synchronisation from title,1 with redirect resolution
- Automatic presentation mode for articles with
presentation: truefront matter
A slug and title are optimising for the same thing, short length and clarity. ↩︎
Post-processor features
- Audio player spectrogram + waveform generation
- Video player automatic poster generation
- Automatic relocation of footnotes to end of section
- Single page bundling, tree shaking, and minification
- Automatic below-the-fold lazy loading
- 400% A+ score on Google Lighthouse
- Automatic image metadata cleaning
- Video/audio codec validation
- Broken link checking (internal always, external on demand)
- Linting of spelling/grammar
- Header linking
- Validation of HTML/CSS/JS
- LaTeX maths rendering
- Automatic inlining of images based on heuristics (SVG and rasterised)
My CV is generated from a YAML template using Hugo and LaTeX with Jinja2. Optimised for file size with ghostscript, cleaned with exiftool and qpdf.
This website and CV are built as a nix derivation.2
Phew! That was dense technobabble! ↩︎
History




- 2005-2006: Microsoft Frontpage based self-hosted from an ADSL connection with Windows XP + Apache
- 2007: Dreamweaver / PHP based custom websites, hosted from ADSL over WiFi with Debian 3.1
- 2007-2009: PHP based custom websites written with Geany, hosted from ADSL from a Linsys NSLU2 and then a Compaq iPAQ
- 2011-2016: Custom SPA blog engine with client-side markdown parsing. Bad for SEO! Hosted on an Ubuntu VM.
- 2016-2017: Ghost with default theme, hosted on a VM. Supplementary aggregator to mix blog posts from multiple sources.
- 2017-2019: Hugo with default Ananke theme, hosted on a VM
- 2019-2020: Hugo with Mediumish theme, heavily stripped back, hosted on a VM
Since 2020, this website is made from scratch with hugo with a focus on typography, quality UX and SEO. Anything off-the-shelf or modified never quite felt right.
How I blog
- Set main headers/sections
- Collect photos and screenshots, often using the favorites feature on iOS
- Automatically insert them into the article with a script3
- Organise images to sections
- Write a section at a time, any order
- I try to tell a story
- I use a lot of multimedia (images, video, audio)4
- I try not to indulge every rabbit hole, instead linking out to other articles
- I keep tangents or comments within footnotes
- I make heavy use of validators and linters to keep the quality high
- I tend to write 5mins to 1hr a day, for a week or so for a typical article5
- I try to make the articles easy to replicate so they’re useful to others
- I follow POSSE principles (publish on your own site, syndicate elsewhere)
Every post represents a Yak shaved, despite attempting not to.
This ended up being the key to actually getting articles written. Handling images is otherwise a pain. I also have a hugo shortcode to handle image resizing, captions and encoding. ↩︎
And my minimal, highly responsive theme to focus on the content ↩︎
That’s how I get all my projects done really – gradually. Sometimes I will dedicate a weekend to get DIY projects done. ↩︎
Projects
Writing a blog post is a great way of finishing a project. It forces me to conclude, limit scope and have something to show for it.
It’s important to accept imperfections in the output – something can be proven ideal in concept without being perfect in practice.
I publish when I feel I have innovated, solved a problem or spent time trying to understand something.
AI Policy
As a software engineer I need to embrace AI. However, I am strongly against AI written articles so do not publish any AI generated content except where noted. All content on this website is written by me.
Alongside traditional linter style tools like proselint, I use AI on this blog to proofread: correct grammar, spelling and other typos.