spaceship-cli got built in an afternoon in March, because I was tired of DNS being the one manual step in my deploys. Most of cricinfo-cli was built by agents while I watched the match. cf-cli, webctx, actions-watcher: each one started as a specific annoyance and existed as an installed, working tool absurdly soon after I noticed the annoyance.
That cadence is the point. Not the tools individually, but the speed of making them. There’s a particular joy in noticing friction in the morning and having the fix be a real published thing by evening, and once you’ve had it a few times you start protecting it. Every one of those tools is Go, and that’s why: Go is the language that doesn’t make me trade any of the things the cadence needs against each other.
Fast to build, fast to run: pick both
Every language forces a version of this choice. A script is fast to write and produces a slow, fragile artifact: fine for me, bad for a tool my agents will invoke hundreds of times in loops where startup time and flakiness compound. Rust produces a beautiful artifact, and I happily pay its costs where they buy something, but for a program that starts, does one job, and exits, the borrow checker is proving things about state the program doesn’t have, and the compile loop drags against the one thing I’m optimizing for.
Go just refuses the trade. Builds are near-instant, so the write-compile-run loop never stalls, whether for me or for an agent iterating on a subcommand. And the thing that comes out is a native binary that’s fast: fast startup, real concurrency, no interpreter tax, without me doing any performance work whatsoever. A CLI doesn’t need to be maximally fast; it needs to be reliably fast, immediately, for free. Goroutines are the clearest case: when a cricinfo query fans out across a dozen paginated endpoints, or webctx asks three search providers the same question at once, the parallelism costs a few lines and it’s the idiomatic few lines, the version an agent writes correctly on the first try.
Strict enough to build in parallel
Here’s the part that matters most now that agents write most of the code: the afternoon cadence only survives parallel building if something holds the pieces together. When cricinfo-cli was being built, a discovery agent was reverse-engineering ESPN’s undocumented API while an implementation agent turned its findings into commands, concurrently in the same codebase with no shared memory of each other’s reasoning. What kept that from becoming mush is that every boundary between them was a type. The weird API shapes became structs; the structs became the contract; the compiler enforced the contract while both agents moved at full speed.
That’s the sweet spot Go occupies. It’s strict where parallel agents actually collide, with types at every boundary, errors as values you visibly handle, and unused imports as hard errors, and relaxed everywhere the strictness would just slow the loop down. Add that it’s a small language with one way to do most things and machine-enforced formatting, and you get code from a rotating cast of agents that reads like it was written by one author. I get Rust-grade confidence that the pieces fit, at script-grade iteration speed. That combination is the whole reason “built by agents in a day, safely” is a sentence I can write without flinching.
Shipping is part of the loop
The cadence doesn’t end at “it compiles”; a tool isn’t done until it’s installed everywhere my agents work, which means fresh sandboxes, CI runners, machines that didn’t exist an hour ago. Go’s single static binary makes that leg instant too: agentbox’s CLI is under 5 MB and runs on a bare machine with no runtime installed. The npm packages I publish are just delivery shims that unpack the right binary per platform, because npm i -g is the command every machine already understands.
webctx is the proof this half matters: the first version was TypeScript and worked fine, and I ported it to Go anyway, because “first install Node” was the slow step in a tool whose entire job is being instantly available on whatever machine an agent happens to be on. And once a tool is a Go binary with a decent command tree, the documentation problem disappears with it. Agents run --help and figure the rest out, which is how cf-cli has stayed documentation-free while growing new subcommands whenever I notice agents reaching for a raw API call often enough.
The cadence is the feature
I still reach for Rust when something is a runtime: long-lived, stateful, holding other software up. But most ideas aren’t that. Most ideas are “this friction shouldn’t exist,” and the value of the fix decays with every day it stays unshipped. Go keeps the entire distance from idea to implementation, parallel agents, binary, and installation everywhere inside a single day without giving up the safety that lets agents cover that distance unsupervised. Fast to build, fast to run, fast to ship. I stopped thinking of it as a language choice a while ago. It’s how I keep the gap between being annoyed and being done small enough that I never talk myself out of fixing something.