Every proposal promises maintainable code. The word survives because it commits nobody to anything: it is a compliment the supplier pays their own work, and by the time you can test the claim, the team that made it has moved on.
It is testable, though. Maintainability is not an aesthetic property of source code - it is a rate. It is what the tenth change costs relative to the first, and it is set by half a dozen decisions you can ask about before signing.
The only definition that matters
A system is maintainable to the degree that a competent developer who has never seen it can make a small change safely, quickly, and without reading all of it.
Three words in that sentence are doing the work. Never seen it - because the people who built it will not be there. Safely - meaning they will know if they broke something. Without reading all of it - because if a two-line change requires understanding the whole system, cost grows with size rather than with the change.
Everything below is a proxy for one of those three.
What actually sets the rate
- Can it be run locally in one command? If setting up a development environment takes a day of tribal knowledge, every future supplier charges you that day, and small fixes stop being worth doing. This is the single best predictor we know of.
- Is there a test suite, and does it run? Not coverage percentage - whether a developer changing something is told when they break something else. Without it, every change is a gamble and the rational response is to stop changing things.
- Are dependencies current and few? A project two major versions behind on its framework is not "stable", it is accruing a bill. The upgrade gets more expensive every year and eventually becomes a rewrite.
- Is the configuration outside the code? Credentials, endpoints and environment differences in files that are edited by hand at deploy time are how staging and production silently diverge.
- Is there a deployment that anyone can run? If releases depend on one person and an undocumented sequence, you have a bus factor of one and a reason to batch changes into risky quarterly releases.
- Does the structure match the business? Code organised around what the business does is navigable by someone who understands the business. Code organised around technical layers requires understanding the whole system to find anything.
What does not predict it
Some things are treated as evidence of quality and are not.
Comment density. Well-named code needs few comments; heavily commented code is often explaining names that should have been better. What matters is comments that record why, which the code cannot say.
Framework choice. A carefully built site on an unfashionable framework outlives an indifferent one on a modern stack. The framework decides your hiring pool, not your maintainability.
Lines of code. A smaller codebase is usually better, but "we rewrote it in a third of the code" frequently means the same complexity moved somewhere less visible.
A style guide. Formatting consistency is worth having and takes an afternoon to automate. It says nothing about whether the system is comprehensible.
Questions to ask before you sign
You do not need to read code to ask these, and the answers are checkable later.
- "How long does it take a new developer to get this running on their machine?" A number in hours is a good answer. A pause is the answer.
- "What happens when someone breaks something? How do they find out?"
- "Who else could take this over, and what would you hand them?"
- "What will the framework upgrade in two years involve?"
- "What are you going to do that you would not do if you were never coming back?"
The last one is the most revealing. A supplier who expects to maintain the result has a different set of incentives from one who does not, and most of what makes a codebase survivable is invisible to a client at handover.
Make it contractual, not aspirational
Move maintainability out of the adjectives and into the deliverables list, where it can be accepted or rejected.
A README that gets the project running from a clean machine. A documented deployment. A test suite that runs in CI on every change. A dependency policy with a named owner. An architecture decision record for the three or four choices that would otherwise be mysterious in two years.
None of that is expensive when it is built alongside the work. All of it is expensive to add afterwards, which is exactly why it needs to be in the scope rather than in the sales deck.