Why this is hard to say out loud
The hardest part of my work isn’t doing it. It’s describing it to someone who has never been shown that their computer is a decision rather than the weather.
Nearly everyone lives inside one ecosystem completely. The apps are the ones that came with it, the settings are the ones somebody chose, and the whole arrangement feels like a fact about the world. It isn’t. It’s a configuration, and configurations can be written down, read, argued with, and replaced.
So the argument has to be shown rather than made. What follows is the smallest version of it: one word, defined properly, and the three steps it implies.
The pitch fails on framing, not on merit. People evaluate Nix as a package manager, compare it to the one they have, and conclude (correctly, at that framing) that it isn’t worth the syntax.
The claim is different: the system’s specification and the system are the same object. Drift isn’t reduced, it becomes unrepresentable. Rollback stops being a procedure and becomes a symlink. Once that lands, the syntax is a rounding error.
So this is the claim in its narrowest form, without the tooling argument attached.
What declarative actually means
Imperative is a list of things you did: installed this, edited that, ran a command you found online at two in the morning. It works right up until you need a second machine, or the same machine next year.
Declarative is the finished description. You don’t tell the machine how to get there; you state what should be true, and matching it is the machine’s problem. If the description and the machine disagree, the machine is wrong and gets corrected; never the other way around.
A configuration is a pure function from pinned inputs to a store path. Same inputs, same output, byte for byte, on any machine that can evaluate it: the build is content-addressed, sandboxed and offline.
The practical consequences are the boring ones that matter: atomic switches, generation-indexed rollback, no partially-applied state, and a diff that tells you exactly what a change did to your closure before you deploy it.
Five words, defined
The vocabulary is the barrier more often than the ideas are. These five carry most of the weight.
Included for completeness; skip it.
What that actually builds
Once machines are text, they stop being separate projects. Below is the shape it takes: a server, a box full of disks, a desk, a laptop, and something that isn’t even the same operating system. They share one description and one private network.
Hover a node. The pale ring is what every machine has, identically. The short accented list is the only part that makes it that machine. Adding another node means writing that short list, not setting up a computer.
The interesting property isn’t per-host reproducibility, it’s fleet composition: hosts are the same module tree evaluated with different imports, joined by a mesh overlay so service discovery doesn’t depend on where anything physically is.
Hover a node for its composition. Shared modules carry the cross-cutting concerns: identity, shell, mesh membership, monitoring targets; so a new host inherits all of them and declares only its role.
Things that exist because of this
Not a portfolio so much as evidence. Each of these came out of needing something to exist and finding it didn’t.
Public work, briefly.