There’s a deep instinct to treat code as an asset. Lines written feel like progress, a big codebase feels like accomplishment, and deleting code can feel like throwing away work. But it’s worth turning that around: the asset is the behavior the software provides — the problem it solves for the people using it. The code is merely the liability you take on to get that behavior. Every line has to be read, understood, maintained, kept working as everything around it changes, and secured against the ways it can go wrong. If you could get the same behavior with half the code, you’d have the same asset and half the liability, and you’d be unambiguously better off.

Once you see it that way, a lot of instincts flip. Two solutions that deliver identical behavior are not equally good — the smaller one is better, because it’s less to carry, not because small is aesthetically nicer. A feature that few people use isn’t free just because it already works; it’s a standing cost, sitting in the code taking up attention, adding surface area to every change nearby, needing to keep working through every migration and refactor forever. The value it provides has to exceed not the cost of building it — that’s already sunk — but the ongoing cost of keeping it alive. A surprising amount of software carries features whose upkeep quietly outweighs their use.

This is what makes deleting code one of the most underrated activities in the craft. Removing code that isn’t earning its keep reduces liability with no loss of asset — you keep all the behavior anyone actually relies on and shed the cost of everything they don’t. It rarely feels like progress, because progress is coded as addition, and there’s a real fear that the deleted thing was load-bearing in some way no one remembers. But the codebase that stays lean is the one that stays fast to work in, and every line removed is a line that can never again hide a bug, break in a migration, or confuse a reader. Subtraction is work, and it’s often the highest-leverage work available.

It also reframes the decision to build. The right question before adding something isn’t “would this be nice to have” — almost everything clears that bar. It’s “is the behavior worth the permanent liability of the code that provides it,” and that’s a far higher bar, because the liability is forever and the niceness is often fleeting. This is the honest core of the instinct to build less: not minimalism for its own sake, but a recognition that every feature is a subscription you keep paying, and the cheapest feature is the one you were talked out of needing. Code you didn’t write costs nothing to maintain, has no bugs, and never breaks a migration.

None of this means less code is always better in the naive sense — you can compress code into something unreadable and clever, and that’s more liability, not less, because now it’s expensive to understand too. The liability is total cost of ownership, not character count: clarity, size, and coupling all feed into it. But the reframe holds and it’s worth keeping close. You are not paid to produce code; you’re paid to produce behavior, and code is the debt you take on to do it. Treat every line as a cost to be justified by the behavior it buys, delete without mourning what stops earning, and be slow to take on debt that a little more thought would let you avoid entirely.