The most reliable piece of software I own is a script that renames scanned receipts. It is forty lines long, it has never had a roadmap, and it has run without complaint for six years. Nobody would call it a product. It doesn't scale, it doesn't sync, and if you asked it to handle someone else's receipts it would probably refuse out of politeness. It does one job, for one person, and it does it completely.
We don't have a good word for this category of thing. "App" is too grand and "script" is too dismissive, so I've settled on calling them small tools — software with the temperament of a hand plane. A hand plane does not want to become a workshop. It wants to make one kind of cut well, sit in a drawer without demanding attention, and be sharpened by its owner when it dulls.
What a tool owes its owner
A small tool owes you three things: it should be legible, so you can read the whole of it in one sitting; it should be repairable, so that when it breaks — and it will, gently, when some format changes underneath it — the fix is an evening, not a migration; and it should be boring, in the honorable sense that a good hinge is boring. My receipt script fails in exactly one way, by printing the name of the file it couldn't parse. That's the whole error handling story, and in six years it has been enough.
Notice what's missing from that list: growth. A bench does not aspire to be a table. The pressure to generalize — to add the config file, the plugin system, the second user — is where small tools go to die. Every option you add is a promise you've made to a future you can't see, and promises compound faster than interest.
The tool you can fix at your own bench, with the skills you already have, is worth ten that phone home for permission.
The habit of making them
Building small tools is less a technique than a habit of noticing. The signs that a task wants a tool are consistent enough to list:
- You've done the same fiddly thing three times this month and resented it slightly more each time.
- The steps are stable — the annoyance is repetition, not judgment.
- You can describe the whole job in one sentence without using the word "and" more than once.
- Getting it wrong is recoverable. Small tools should practice on things that can be un-broken.
When a task passes that test, I give it an evening. Not a weekend
— an evening. The constraint is the point: whatever you can build
in an evening is small enough to still understand in five years.
Most of my tools begin life as a shell alias, get promoted to a
script when the alias grows a second line, and stop there. The
promotion path ends at ~/bin; nothing I own has ever
needed to leave it.
The bench metaphor holds up better than most, because a bench is also where tools earn their keep. Here is the current population of mine, honestly accounted:
| Tool | Its one job | Age |
|---|---|---|
| receipts | Rename scans by date and vendor | 6 years |
| stow-notes | File a note into the right month's folder | 4 years |
| pressgang | Build this site from a folder of text | 3 years |
| whatport | Say what's listening on a port, in words | 2 years |
Four tools, fifteen years of combined service, zero updates I didn't choose to make. I know professional software with worse uptime and considerably worse manners.
There is an argument that this is all nostalgia — that real work happens in real systems, and the small tool is a hobbyist's indulgence. I'd put it the other way around. The small tool is where you find out what software is like when nobody is trying to keep you inside it. No metrics, no retention, no reason for it to want anything from you at all. Just a job, done, and a quiet drawer to go back into.
Build one this month. Something trivial. Rename your receipts.
The point isn't the minutes saved — it's the standing reminder,
sitting there in ~/bin, that the tools can still
belong to you.