RSS Amplifier

Ben’s Guide to Software Development · Jul 12, 2026

Code is not (just) a liability.

0
Sign in to vote or save

Ben Christel · Ben’s Guide to Software Development

I have seen the claim that “code is a liability, not an asset” many, many times. Just search Kagi for that phrase and you’ll get a bunch of results, topped by Cory Doctorow’s excellent article on the subject. His arguments are correct as far as they go, but they don’t paint a complete picture. Today I want to fill in the gaps in that picture, and see how much of a mess I can make.

The claim that “code is a liability” is often followed by “…but the software’s functionality is an asset, because it’s what the company sells.” This is also wrong. Not entirely wrong, just wrong enough to be misleading.

First things first, some definitions: an asset is something of value that you either have or are due to receive. A liability is money that you owe or expect to pay to someone else.

(Sorry if this is not quite accurate. I am not an accountant or a finance person. Hopefully it is close enough for our purposes.)

Here’s where things get slightly complicated: a physical thing that you own can represent both an asset and a liability on the balance sheet. For example, say you own a truck, and you use it to transport stuff and get paid for that. The truck is an asset: it helps you make money over time, and you could sell it for a big chunk of money all at once. But it also comes with liabilities: you expect to have to pay for insurance and maintenance. The total value of your trucking business (the equity) is the assets minus the liabilities.

Now we are prepared to tackle four questions:

  • Is code an asset?

  • Is code a liability?

  • Is functionality an asset?

  • Is functionality a liability?

The answer to all of these questions is “yes.”

Does your code have monetary value? Could you sell it? Would anyone pay for it?

Well, someone paid you for it, didn’t they?

Code is valuable because it embodies both knowledge and power: the knowledge of how to solve a problem computationally, and the power to actually execute the solution on a machine. Programming is the task of discovering the necessary knowledge and representing it in a form that is both readable and executable. Programming takes effort and insight, and those cost money. The reason we’re willing to spend that money is because the artifact produced (the program) encodes the solution in a form that’s cheaply reproducible — vastly cheaper than having a person solve the problem each time it arises.

For example: suppose you want to solve the problem of serving HTTP requests for your website. In order to do this, you will need to have (or hire) knowledge of how HTTP works. Are you going to pay the person who knows HTTP to sit at a terminal, reading HTTP requests off the screen and typing HTML in response? No! Of course you’re not going to do that — even though it would produce the desired functionality. If you expect to serve more than two or three requests per year, it’s more cost-effective to have that person write a program that encodes their knowledge of HTTP, and can be run infinitely many times at very little cost.

In other words… you pay them for the code. Because code is an asset.

Just to drive the point home: suppose that, while you were writing your program to serve HTML over HTTP, your competitors in the website business were building “datacenters” full of really fast typists and paying them to serve webpages manually. Don’t you think they’d be a little envious of your program? Don’t you think they’d pay to have a peek at it?

Code costs money to maintain. Every time someone has to read it and understand it, it costs. Every time it needs to be changed, it costs. The human and technical forces surrounding the code are constantly shifting; if the code isn’t updated to match, its value slowly erodes as it becomes a poorer and poorer fit for those forces. In other words, code depreciates, much like a physical machine.

All these costs mean that code is a liability. Cory Doctorow said it best, so I won’t dwell on this point. You can go read his article.

Yet, this doesn’t contradict anything I said above. Remember, code is a thing, and assets and liabilities are entries on a balance sheet. Like a truck owned by a delivery company, code can be represented in both places. Its total value is the difference between how much money it makes and how much it costs over time.

On the face of it, it seems obvious that the functionality of a program is where all its value is. Software that doesn’t do anything useful has no value.

The thing is, functionality is only in the here and now. It’s fleeting, momentary. Functionality means you did something useful and got paid for it. If you want to get paid again, you have to do the thing again.

By contrast, code is all about the future. You invest in code now to have cheaper functionality or more functionality later. So while functionality is clearly a good, it’s not the only good. Both the present and the future are important.

This point may be the most underappreciated of the four. Functionality comes with a price — sometimes, a ruinous one.

When you build a feature and release it to production, I want you to imagine that you are making a pact with the devil. Seriously! When you push a feature to prod, you are making a promise that may be very costly to keep, and very hard to wriggle out of.

When you release functionality, you are making a promise to your users that the functionality will continue to exist in the future. If you break that promise, you will piss them off. At the same time, keeping the promise may only be possible at great expense.

Functionality is thus very much like a debt — a liability.

Have you ever been working in legacy code and thought “this code is such crap — why can’t we just throw it all away?” And then immediately thought “oh right, because it’s supporting millions of users.”

See, it’s really the code’s functionality — the fact that it’s doing something useful for people — that makes it such a pain to work with. If no one were using it, you could just delete it!

If only you could wave a magic wand and get rid of all your users, tidying up legacy code would be a piece of cake! Just throw away the codebase and write a new one from scratch. No need to worry about backward compatibility or data migration. Too bad those pesky users are the only thing paying your salary. Too bad you (or your predecessors) made promises to them that now you’re reluctant to keep.

We want to maximize the asset value of our code and minimize its liabilities. That means:

  • Design code that will depreciate slowly. Code depreciates when its assumptions about the world are invalidated, so try to minimize how much your code knows, both about third-party services and about your own features du jour. Push as much code as you can down into the application-agnostic lib and platform layers of your codebase (see Diamond Design).

  • Maximize optionality. Your needs will change in the future. Though you can’t foresee exactly what those changes will be, you can write code that has a good chance of surviving and adapting. Don’t make code configurable; instead, divide it into cohesive, composable pieces. See my essay on Alexandrian Software for more details.

  • Beware of feature bloat. Remember: pact with the devil. Every feature you release is a debt that may come due when you can least afford to pay it.

The next time someone tries to tell you that code is only a liability, remember that well-designed code is an investment in the future. It gives you power and options. Trying to minimize code and maximize functionality is like hiring typists to serve HTTP requests: a recipe for short-term success and long-term disaster.

Read the original on bensguide.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.