What Makes Code Maintainable?

Maintainable code is code someone can change without first reconstructing the author’s entire thought process. That someone may be a colleague, or it may be you six months later with no memory of why doStuff() exists.

Name the thing it actually does

Names should reveal purpose. processOrders() tells me more than doStuff(), and isPaymentOverdue tells me more than flag.

Consistency matters too, but the exact convention depends on the language and codebase. Follow the established style unless there is a good reason to change it. A project using three naming systems is not made clearer by adding a fourth correct one.

Keep the path through the code visible

Prefer straightforward control flow over clever nesting. Split a function when it is doing several independent jobs, not merely because it crossed an arbitrary line count.

Comments should explain decisions, constraints, and surprising behaviour. They should not translate obvious code into English:

// Retry once because the upstream service occasionally closes idle connections.
const result = await retryOnce(fetchReport);

That comment may save someone from “cleaning up” behaviour the system relies on.

Limit what each part needs to know

Small modules and functions are easier to reason about when their inputs and outputs are clear. Avoid hidden global state where a dependency can be passed explicitly.

This does not mean every three lines need a new abstraction. A helper used once can make the code harder to follow if its name only sends the reader to another file. Extract concepts, not line counts.

Protect behaviour with tests and version control

Automated tests make changes safer, especially around business rules and bugs that have already happened once. Test observable behaviour rather than private implementation details where possible; otherwise a harmless refactor can require rewriting half the test suite.

Version control records what changed and lets a team review it. Small, focused commits are easier to understand and revert than a week of unrelated work labelled “updates.”

Code still needs occasional refactoring. Do it when duplication, confusing dependencies, or repeated bugs show that the current shape is getting in the way. Refactoring everything because it no longer matches today’s favourite pattern is usually less helpful.

Simple code is not code with the fewest characters. It is code whose behaviour, dependencies, and reasons are visible enough that the next change is boring. Boring changes are underrated.