- Published on
Good tools are invisible: gingerBill on friction as a feature, and where "invisible" hides failure
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction — the argument that good tools disappear
- Where I agree — selling friction as a feature
- The trap of tools that are too invisible
- Invisible in use, loud on failure
- Closing
- References
Introduction — the argument that good tools disappear
gingerBill — the author of the Odin language, so very much a toolmaker — recently wrote "Good Tools Are Invisible," and it reached the top of Hacker News. The thesis is exactly the title: a good tool should be invisible, and building such tools is the toolmaker's goal. The habit he keeps pushing back on is taking a tool's shortcomings and reselling them as a fun puzzle to solve. He does not want his tools to be fun. He wants them to disappear.
The sharpest part is a psychological one: the gap between feeling productive and being productive. Solving a hard problem with a difficult tool feels great, and people mistake that feeling for output. The honest metric, he argues, is wall-clock time and how many mistakes you made getting there. When you are fluent with an editor it melts into the background — but the moment it cannot handle something easily, it becomes visible again.
The rest hangs off that axis. Multiple cursors beat vim macros most of the time; strong defaults are a form of respect for the user's time; in his words, "A learning curve is a cost, not a virtue." When a tool becomes part of your identity, admitting its flaws feels like admitting something about yourself, which blocks honest evaluation. He explains the programmer's love of endless configurability as accidental complexity. Importantly, he does not attack people who genuinely find vim or emacs productive. His target is the thinking that dresses friction up as a virtue, not the tool choice itself.
Where I agree — selling friction as a feature
The strongest idea, to me, is that feeling-versus-being distinction, because I live it daily. Format-on-save, LSP completion, a keymap that fits my hands — when these work, I never think about the editor. The instant the language server hangs or completion surfaces nonsense, the tool is visible again. "Does it disappear once you are fluent?" is a genuinely useful test.
He also argues that the limits of GUIs are not inherent but come from toolmakers not putting in the effort, and rejects the idea that terminal UIs are inherently better. I mostly agree. A well-built GUI — a good profiler, a diff view — can be as invisible as a terminal, sometimes more so, because it shows you structure a terminal makes you rebuild in your head. "TUI versus GUI" is the wrong axis; "how many puzzles does it hand me" is the right one.
I also agree about the rhetoric. "You will get faster once you learn it" is often a sunk-cost sentence: we have already invested the time, so we promote the difficulty itself into a virtue. Measuring by wall-clock time and mistakes instead of by the satisfaction of the puzzle is not sentimentality — it is engineering.
The deepest sign is a subtler one. When a tool is truly invisible, I stop having opinions about it at all; there is nothing to call good or bad — the state gingerBill describes as forgetting you are using it. Conversely, if I am in an editor argument right now, then for that moment the tool is, at least, not invisible to me.
I will push back on one line. Calling macros worse than multiple cursors "99.999%" of the time is rhetorical. Macros record, replay, and can be saved and version-controlled — things multiple cursors do poorly. Yet his deeper point still holds: measure the output, do not romanticize the tool. The pushback dents the example, not the thesis.
The trap of tools that are too invisible
Here a working-engineer caveat comes in. gingerBill's "invisible" means the interface creates no friction. But there is a second axis of invisibility: a tool whose internal behavior is opaque. These are not the same thing. The first is good; the second is dangerous.
Build systems are the classic case. When the cache is warm and incremental builds are fast, the build tool is perfectly invisible. The trouble starts when it will not tell you why the cache missed, or why CI suddenly takes forty minutes. A tool that is invisible when it works and still invisible when it breaks is not elegant — it is unobservable.
Kubernetes operators make this vivid. You declare desired state and the operator reconciles it for you; it needs no attention, so it goes invisible. That same invisibility means when reconciliation quietly stalls — a stuck finalizer, a dead admission webhook, a CRD field it silently ignores — nobody notices. The comfort of declarative tooling is often paired with the cost of not knowing what is happening. I once found nodes that had sat unschedulable for weeks before anyone caught it (postmortem), precisely because the tooling was too quiet.
There is a deeper cost here. An invisible abstraction carries your competence for you — and the moment it leaks, the only people left are the ones who never looked underneath. That is Joel Spolsky's point that all non-trivial abstractions leak. If kubectl apply always "just works," the day it does not, the on-call engineer has never had to learn what sits below. The more invisible a tool, the better — but invisibility does not make what is underneath go away.
Invisible in use, loud on failure
So I add one axis to gingerBill's test. A good tool should be invisible while you use it and, at the same time, become loud and legible the moment it breaks. Invisibility of friction (good) and silence on failure (bad) are separate axes. Overlay them and tools fall into four quadrants.
loud on failure quiet on failure
───────────────── ──────────────────── ────────────────────
invisible in use tools you trust the most dangerous
annoying in use honest but unfinished worst — slow and dark
The tools I trust most sit in the top-left: invisible day to day, noisy when they fail. The most dangerous sit top-right, equally quiet whether they work or not. This complements rather than contradicts him. To the strong defaults he rightly champions, I pair observability.
A good operator emits conditions, events, and metrics: it needs no hand-holding, but when you look, it tells you what it is doing. The time a small operator I wrote in Rust caught a fleet that was already down (that story) was, in the end, a case of making the tool loud. It is the same reason "magic" frameworks are risky — invisible while their guesses are right, and offering no surface to debug the moment a guess is wrong.
Legibility should not wait for failure either. The best tools let you make them visible on demand — --dry-run, kubectl describe, a query's EXPLAIN, a build's --verbose graph. Invisible by default, inspectable the moment you ask. That on-demand visibility is what lets you keep a mental model without paying attention every day.
Closing
The essay is worth your time. The diagnosis — that reselling friction as fun is a rationalization — is correct, and "does it disappear once you are fluent?" is a good litmus test for choosing tools. I do not have much quarrel with his conclusion.
The caveat I would add from the field is a second question: "does it come back, loudly, when it breaks?" Invisible in use, legible in failure. The tools that clear both bars are the ones I have ended up trusting for years.
Underneath his point and mine is the same value: respect for the user. He asks tools to respect your time; I am asking them to also respect your understanding. A tool that saves my time today but strands me when it breaks has not saved that time — it has only borrowed it.
References
- gingerBill, "Good Tools Are Invisible" (2026-07-10)
- gingerBill's blog
- Joel Spolsky, "The Law of Leaky Abstractions" (2002)
- Fred Brooks, "No Silver Bullet: Essence and Accident in Software Engineering" (1986) — the source of the accidental-vs-essential complexity distinction gingerBill invokes.