Projects
These are some of the open-source side-projects I've worked on recently. You can find more on my GitHub profile.
Self-hosting
I like to self-host things as much as I can, and that requires some infrastructure. There's a lot of ready-made software that fills that gap, but sometimes none of it quite works how I want it to.
Centauri
A reverse proxy that's super easy to configure, obtains certificates automatically from an ACME provider like Let's Encrypt, and can even expose services over Tailscale instead of the public Internet.
Goplum
A simple, self-hosted monitoring service. Periodically runs checks and sends notifications when things go wrong.
certwrapper
Wraps another binary, and manages obtaining a certificate for it from an ACME provider (such as Let's Encrypt). Whenever the certificate is updated, the child binary is sent a signal so it knows to reload.
Dotege
A tool to generate configuration files based on currently running Docker containers. Originally designed to be used for haproxy, I now use it to generate a configuration file for Centauri.
fontl
Simple web app that lets you upload fonts, preview them with custom text and font size, and tag them with usage information.
tsp
A small Tailscale proxy for TCP connections. Run it alongside another service (like a database or IRC bouncer) and it will allow you to access it securely over your tailnet.
tsv
A small Tailscale node that relays traffic to a Wireguard VPN. Useful for making exit nodes or custom app connectors that route traffic over a commercial VPN.
umami-exporter
Prometheus metric exporter for Umami (a self-hosted web analytics tool). Umami doesn't expose the data nicely, so umami-exporter queries its database directly.
Go libraries
Go is my favourite language for writing software in, and I've built up a small collection of libraries to make things easier.
aca
A generator for unique, human-friendly identifiers. Useful when users may need to share codes with each other, such as when inviting them to play a game. Each identifier is an adjective, colour and animal, like 'satisfied-yellow-tapir'.
apkutils
Utilities for operating on Alpine Linux packages and package indices. Supports verifying public key signatures, parsing package lists, and so on.
config
For desktop applications that need to persist user configuration. Handles storing and loading a YAML file in the appropriate location (%AppData% on Windows, ~/.config on Linux, etc).
envflag
Allows setting standard Go flags via environment variables. Lets you write simple code, while still supporting configuring the app nicely when using Docker/Kubernetes/etc.
gitrefs
Provides a simple way to list references from a remote git repository over HTTP, without needing a full git client or a checkout of the remote repository.
hotsource
Enables live reloading of web-based frontends when files are changed on disk with minimal setup.
latest
A library that lets you find the latest versions of software, packages, images, etc.
legotapas
Provides build constraints for the lego library. This allows you to build applications that obtain certificates using ACME DNS challenges with a specific provider without having to bundle 30+MB of dependencies.
middleware
Common, framework-agnostic middleware for use when writing Go HTTP servers.
slogflags
Defines two flags to control Go's structured logging package (log/slog). These permit users of your apps to set the logging level and format easily, with no boilerplate on your side.
Tools and services
Utilities and services and other things I've written that I can't nearly categorise any further.Alphabat
Simple command line tool to retrieve the battery status of a HyperX Cloud Alpha Wireless headset. (This also has the side effect of making the headset report the correct battery level when pressing the power button.)
BASS
Batch Audio Selection for Subsonic. Tool to automatically generate semi-random playlists from your music collection on a Subsonic server.
Contact form
A simple web service that allows users to type into a form, and send you an e-mail. Supports CAPTCHAs to prevent spam, custom templates, etc.
Contempt
Container file templating engine. Allows you to generate a Dockerfile (or Containerfile) from a template, substituting in the latest version of its dependencies, packages, and so on.
GitHub release redirector
Redirects HTTP requests to assets from the latest release of a GitHub project. Designed to enable simple automatic updates in clients.
gofish
A tool that can be dropped into a coding agent "I'm done" hook, that automatically checks for code issues (code style, static analysis, failing tests, etc) and reports them to the LLM fix.
jewelcase
A small program that transforms an album art image to look like it's inserted into a CD jewel case. Make your music collection look like it's straight from the 2000s!
Puzzad
A web-based, self-paced puzzle hunt. The site is open source: it uses a Go backend and a Svelte frontend. The puzzles are not open source, but there are several 'adventures' available to play for free!
Splendid
A multi-player, web-based board game engine. It features a nodejs backend that handles game logic, and a Svelte-based frontend that displays the game state and allows players to interact with it.
Todoistager
Tool to automatically apply age-based labels to tasks in your Todoist account, so you can review those that have been hanging around for way too long.
Webhooked
Command-line utility to automatically adds a webhook to all of your GitHub projects. Because for some reason there's no account-wide webhooks. Still.