Does code quality still matter?
Every week someone posts that code quality is dead. AI writes the code now, so who cares if it's messy? regenrate it.
And every week someone replies that this is how you end up with an unmaintainable pile that breaks in production.
Both of them are right, about different software. The argument never ends because nobody says which software they mean.
Ask a senior engineer, and you'll get a classic answer: it depends. That's true, but it's not useful until you can say what it depends on. So let's work that out.
Code quality was never about pretty code
Start with why code quality mattered in the first place. "It feels good" isn't a reason.
Anything you want to do with software, whether that's shipping a feature, scaling a system or fixing an incident, comes down to two things:
- Understanding what the system actually does. Not what the docs say, but what it really does.
- Changing it safely, without breaking what already works.
That's all code quality is for. Readable names, tests, clear module boundaries, linters, observability: each one exists to make a system easier to understand or safer to change.
A one-line program needs none of it. You can see everything it does and change it without fear. A real system, like a browser with millions of lines and thousands of interacting parts, has more possible behaviors than anyone could describe. You can only reason about it piece by piece, through components that have a clear identity. Structure is what makes a large system understandable. That's why we have code, rather than one endless list of machine instructions.
The compounding trap
Every change to a system carries two risks:
- You introduce a problem now. Not only a bug: a project that runs twice as long as planned, a feature that doesn't work the way users need, a blown budget.
- You make future problems more likely. The change leaves the system harder to understand.
The second risk feeds the first. Harder to understand means riskier changes, and riskier changes leave the code harder still. It isn't linear, it compounds. Read enough postmortems and almost every one comes down to this: the system, or one part of it, was too hard to understand.
Let that run long enough and you end up somewhere every engineer has seen: a codebase where every change breaks something.
Code quality exists to keep you out of that trap. Hold that thought, because it explains when quality stops mattering.
AI is mass-producing a different kind of software
Software you can throw away has always existed. AI is about to make it the most common kind there is.
Picture software where:
- Failure barely matters. If it breaks, nothing important breaks with it.
- Almost nobody depends on it. Just you, or a few people who don't mind if it changes.
- Replacing it is nearly free. You could regenerate the whole thing in an afternoon.
- Maintenance is irrelevant. You'll never come back to it.
A planner for one birthday party. A calculator that works exactly the way you like. A script that cleans up one CSV. A dashboard for this week's launch.
None of that software lives long enough to hit the compounding trap. There's no future change to make harder. For disposable software, code quality doesn't matter. Spending effort on it is waste.
Now picture the opposite: software that runs for years, that millions of people or hundreds of other systems depend on, where a failure costs real money or real trust, and that needs a team maintaining it all the time. Payments, auth, your core APIs.
For durable software, code quality matters as much as it ever did.
The biggest misreading: "durable engineering is over"
The loudest take online is that AI makes engineering rigor obsolete. It's backwards.
Durable systems will stay the most important software in the world. There will also be more of them, because AI tools make durable software easier to build too. What changes is the count: disposable software will vastly outnumber everything else.
So it isn't that one replaces the other. Both grow, at different rates and for different reasons.
It's a spectrum: score four dials
Durable and disposable aren't two boxes. They're the two ends of a scale, and the amount of rigor you apply should move along it. Place any project by scoring four dials:
| Dial | Disposable end | Durable end |
|---|---|---|
| Consequences of failure | Nothing important breaks | Real damage to money, users or trust |
| Dependents | You, or a few people who don't care | Millions of users, many systems |
| Cost to replace | Hours | Months or years |
| Cost to maintain | Basically free | A team, forever |
All four low: skip the rigor and move fast. All four high: apply everything we've learned over the last few decades.
And when you're not sure, assume it's more durable than you think. Every engineer has watched a "quick prototype" become the production system. Guessing too low is the expensive mistake.
You can make software more disposable on purpose
This is the part I find most interesting. You don't just discover where a project sits on the scale. You can design it toward the disposable end.
Isolation (no blast radius). Give it an environment with only its own data: no customer data, no PII, no production credentials. Whatever runs there can fail safely.
Independence. Nothing else is allowed to depend on it. For example, block inbound API calls from production systems into that environment.
Redundancy. Keep a boring, clunky, durable system as the backup. Then let people vibe-code faster front ends on top. When one breaks, and it will, they fall back to the old one.
Limited scope. One user, one event, one week.
Designing for disposability is a discipline in its own right. Most teams spend all their energy making durable systems more rigorous and none on making the rest safely throwaway.
The real lever: make rigor cheap
Here's the move that makes the whole debate easier.
You'll never place every project correctly. The "disposable" internal tool will gain users and a dependency, and one day it will need to be durable. So the real question isn't which side you pick. It's how expensive it is to be wrong.
If rigor is cheap, being wrong is cheap too. Upgrading a project from disposable to durable becomes a small step instead of a rewrite. That comes down to foundations:
Standardize. Every language, framework and protocol you allow multiplies the linters, security practices and expertise you need. One standard stack removes whole categories of work. Use checks that just run. The best tooling runs automatically, without anyone choosing to run it or knowing how it works. It's fast, quiet and rarely wrong. When it's that cheap, it's worth running even on disposable code. Make testing boring. Every test fast and deterministic, with no testing expertise required. One example: every service ships an in-memory fake that other teams can test against. That used to be a dream. Coding agents can now write those fakes, but someone still has to decide to do it and make them available to everyone. Be strict from day one. Turn every lint rule to maximum, everywhere, from the start. It ends whole categories of debate. Ask anyone who has tried to switch on a linter in a million-line codebase and faced a hundred-thousand-line diff.
So: does code quality still matter?
"It depends" can finally become an actual answer:
- For disposable software? No. Ship it, use it, throw it away.
- For durable software? Yes. As much as ever, and there will be more of it.
- Does it have to be expensive? No. Spend on foundations so rigor stays cheap, and being wrong about which kind you're building stops being a disaster.
Before your next project, score the four dials, and decide whether to design it toward disposable on purpose. Then invest in whatever makes rigor cheap for everything else.
The durable vs. disposable framework comes from Max Kanat-Alexander's talk at AI Engineer, "Does Code Quality Still Matter? It Depends on This." Worth the 16 minutes