What's worth writing when code is cheap.
Writing code got cheap, but owning it didn't — and the gap forces a sharper line between disposable code, durable code, and the things you probably shouldn't build at all.
The naive view is that since AI lowers the cost of writing code, we should write more of it. Why deliberate over a feature when you can prototype five versions by lunch? The conclusion seems to follow, but I think it gets the economics backwards.
Writing code has never really been the bottleneck for most software. Reading it, debugging it, deploying it safely, integrating it with other systems, keeping it working as the world around it changes — these dominate the lifecycle cost, often by an order of magnitude. AI compresses the writing step dramatically and the others much less. So if anything, the ratio of write-cost to live-with-cost has gotten worse, not better. Code that was barely worth writing before is now trivially easy to write and just as expensive to own. The temptation to generate it has gone up; the wisdom of generating it has gone down.
This makes scope discipline more important, not less. Every feature, endpoint, config option, and abstraction is a small ongoing tax — a thing that can break, that someone has to understand later, that constrains future changes, that has to be kept secure. When writing was expensive, the cost of writing acted as a natural filter; a lot of bad ideas died because nobody could be bothered to implement them. That filter is gone. Whatever replaces it has to be deliberate: a clearer sense of what the system is for, a higher bar for what gets in, more willingness to delete.
Small scope also matters because verification hasn't gotten meaningfully cheaper. AI can produce a 2,000-line module in a minute, but a human still has to convince themselves it's correct, and that takes about as long as it always did — longer, sometimes, because the code doesn't carry the author's intent the way human-written code does. A small, sharply-scoped system you can hold in your head is verifiable. A sprawling one generated in an afternoon is just a liability with good test coverage.
There's a more subtle thing happening with abstractions, too. Good abstractions used to emerge partly from the pain of repetition — you wrote something three times, noticed the shape, and factored it out. When code is cheap, the pain signal weakens, and you get either premature abstractions (AI-suggested patterns imposed too early) or the opposite, sprawling parallel implementations that never get unified because each one was cheap to produce. Both are worse than what a thoughtful human under cost pressure would have built.
Two regimes
"Code being cheap" isn't a uniform shift, though. It's a wedge that splits the world of software into two regimes with very different economics.
In the disposable regime, code's purpose is to run once or a few times and then vanish. Data migrations, scratch analyses, scrapers for a specific moment, glue between two systems for a weekend, internal dashboards for a question nobody will ask again next quarter. Maintainability is genuinely a non-issue because there's nothing to maintain — the code's lifespan is shorter than the half-life of the assumptions it encodes. Here, AI is close to pure upside. The traditional advice ("write it well, you'll thank yourself later") was always partly wrong for this regime; it just wasn't worth distinguishing, because writing throwaway code carefully cost almost the same as writing it carelessly. Now the cost gap is huge, and the right move is to lean fully into disposability — accept the mess, get the answer, delete the artifact.
In the durable regime, everything above applies and then some. And the wedge gets sharper because the same productivity boost that lets you spin up a one-off script in five minutes also tempts you to spin up a "small service" in an afternoon that will then live for eight years. The danger isn't writing more code per se; it's misclassifying durable code as disposable at the moment of creation, when the cost of being wrong is invisible. A lot of bad long-lived systems started life as someone's quick prototype that worked well enough to ship.
The underrated capability
The most underrated effect, I think, is on abstractions inside existing codebases. Previously, improving an abstraction across a large codebase was a project: you'd weigh whether the win justified the churn, and often the answer was no, so cruft accumulated. Now you can do it in an afternoon, which means the equilibrium shifts. Abstractions that were "good enough given migration cost" no longer are. Codebases that don't actively improve their internal vocabulary will feel increasingly creaky against ones that do. Refactoring stops being a periodic cleanup event and becomes closer to a continuous practice — you fix the shape of the code as soon as you notice the shape is wrong, because the cost of fixing it has collapsed.
Internal tools, the interesting middle
Internal tools sit somewhere interesting on the disposable/durable spectrum. They're often durable in calendar time but disposable in commitment — they're allowed to be ugly, narrow, and brittle in ways customer-facing code isn't. AI is unusually well-suited here, because the quality bar is "solves the problem for the five people who use it" rather than "withstands adversarial input from millions." A lot of organizations underbuilt internal tooling for decades because the labor cost couldn't be justified against a small user base; that math has now flipped entirely, and I'd expect the internal-tools surface area inside good engineering orgs to expand significantly over the next few years.
What not to write at all
There's a deeper question upstream of all of this, though. The regime distinction is useful, but the binding constraint isn't really writing or even refactoring — it's attention. Every piece of code you own takes a permanent slice of finite human bandwidth: someone has to read the PR that touches it next year, debug it at 3am when a dependency changes, decide what to do when a CVE drops against a transitive dep, hold its shape in mind when designing the thing next to it. AI helps with all of those locally — patches, fixes, summaries — but the deciding still routes through a human, and the human's bandwidth is fixed. Token spend lands on the same bill: an agent traversing 200kloc to do a small thing costs more than one traversing 20kloc, forever.
So the question that probably matters most isn't "which regime is this code in" or even "should I write this well or quickly," but "should this code exist in my life at all, or am I better off taking someone else's slightly-worse version and never thinking about the problem again." AI makes the surface appeal of building obvious — we could just build our own now — but the deeper analysis usually argues the other way. The interesting failure mode of cheap code isn't bad code. It's a quietly expanding surface area of things you're now responsible for, none of which individually seemed like a bad idea at the time.
The line of "obviously don't build this yourself" has been moving down the stack for a long time, and AI is moving it faster. Things teams comfortably built in-house a few years ago — auth, search, feature flags, job queues, admin panels, observability glue, large chunks of internal platform engineering — are now better consumed than built for most. Not because building them is hard. Because owning them is. The gap between what we could build and what we should own is probably the most important thing to keep an eye on right now.
The synthesis
The old default was treat all code as if it might become durable, because you can't afford to rewrite. The new default has two layers. Upstream: don't write the code at all if a workable version of it exists in the world and you can live with workable. Downstream, for whatever survives that filter: decide which regime it's in, and commit to that regime's discipline. Disposable code gets fully disposable treatment — fast, ugly, gone. Durable code gets more care than before, not less, because the surrounding ocean of cheap code makes the durable parts harder to keep clean.
It's true that AI also lowers the cost of converting between regimes — promoting a prototype, breaking up a monolith, rewriting once you know what it should have been. Within the regime layer, misclassification is more recoverable than it used to be. Conversion costs don't fall by the same factor that writing costs do — the human decisions that separate a prototype from a production system (error handling, security model, ownership, runbooks) resist the same compression typing has undergone — but they fall enough that "commit at creation" is weaker than it might first sound at this layer.
The upstream layer is a different story. Once you've built a thing and woven it into your stack, the decision to keep owning it is mostly already made: migration costs are concrete, ongoing ownership costs are diffuse, sunk cost and status quo bias both pull in the wrong direction. Migrating off your own auth onto a vendor, or off your own job queue onto a hosted one, is the kind of project that gets perpetually deferred. Build-vs-buy misclassifications are close to one-way doors. That's the layer where "commit at creation" actually does most of its work — and AI doesn't just fail to help you back out, it actively pushes you in. Tasks that used to be obviously too much to take on now look feasible, because the writing demo is fast and concrete while the ownership cost is slow and invisible. Build-vs-buy is exactly where AI makes its most seductive case, and exactly where that case is least to be trusted. The writing got cheap. The owning didn't. The decision has to be made on the owning.
The skill, maybe, is twofold: knowing what not to take on at all, and being honest about which regime everything that survives belongs to.