What I build

I have an intolerance for half-measures. A Go TUI for a productivity system I actually use; a Tauri desktop app where the real problem was making XSD validation semantically aware rather than structural; a Neo4j-backed fiction engine where the relationships between characters are the data model.

In fac-cra, I turned a blunt approval queue into a set of configurable segments with their own independent logic. In Workwise, I replaced a tangle of loading booleans with a discriminated-union state machine.

How I work

I was a theatre director. I wrote a book on interactive theatre ("Creating Worlds", Nick Hern Books, 2017), and ran courses at drama schools. During lockdown I started learning ink, Inkle's scripting language for interactive narrative, and kept going from there.

Left to my own devices, I take things further than anyone asked. Iris is built on a single TypeScript core driving three completely different interfaces: an OpenTUI terminal UI, direct CLI commands, and a Tauri desktop app in Rust. Wyrd has its own Cypher-subset parser and a binary merge driver for conflict resolution, because I wanted a proper graph query language over JSON files rather than a workaround. This portfolio tracks itself through a bespoke git-metrics CLI with a typed JSON Schema contract, because I have ADHD and it is genuinely easier for me to build the infrastructure to automate the maintenance than to do the maintenance.

On team projects I tend to land between architecture and delivery.

The toolkit

TypeScript for anything where state needs to be modelled explicitly: discriminated unions, exhaustive type narrowing, no runtime surprises from a function that lies about what it returns. Go when the output should be a binary. Svelte 5 with runes on the frontend; PostgreSQL when the relationships are incidental, Neo4j when they are the model. I have written enough Rust to ship a Tauri desktop app and know when to stop.

Get in touch