Nobody Reads Code, They Read Your Explanations Disguised as Code
A few years ago I opened a file I'd written eighteen months earlier, needed to fix a bug in it, and had the deeply humbling experience of not understanding my own code. Not "it took me a minute to remember" — I mean I genuinely could not tell what processData(x, y, flag) was supposed to do without stepping through it in a debugger, and I was the one who wrote it. That moment reframed how I think about readability. It's not a nicety for junior developers or a checkbox for code review. It's a message you're sending to a future reader who has none of the context currently living in your head, and that future reader is very often you.
Names carry more information than people budget for
The single highest-leverage readability habit I know is also the least glamorous: name things for what they are, not for how you first thought about them while writing the code. I used to write things like this constantly:
function proc(u, d) {
const r = u.items.filter(i => i.d > d);
return r;
}
I knew what u, d, and r meant at the moment I wrote it. Two weeks later, nobody knows, including me. The rewrite costs nothing in runtime performance and everything in comprehension speed:
function getItemsOrderedAfter(user: User, cutoffDate: Date): OrderItem[] {
return user.items.filter(item => item.orderedDate > cutoffDate);
}
The function name now tells you what it returns and what determines inclusion, without opening the body. That's the actual test I use for a good name: could someone calling this function guess its behavior correctly without reading the implementation? If not, either the name is wrong or the function is doing too many unrelated things to be nameable in the first place, which is itself useful information — bad names are often a symptom of bad decomposition, not just a labeling problem.
I'd extend this past variables and functions to booleans specifically, because ambiguous booleans are a recurring source of real bugs, not just readability friction. if (status) tells you nothing. if (isPublished) or if (hasExpired) tells you exactly what branch you're in without checking the variable's declaration.
Comments should explain why, almost never what
I went through a phase early in my career of over-commenting, narrating every line like a play-by-play:
// increment the counter
counter++;
// check if counter is greater than max
if (counter > max) {
This is worse than no comment, because it adds visual noise without adding information — anyone reading counter++ doesn't need it translated into English. The comments worth writing explain the why that isn't recoverable from the code itself: a business rule, a workaround for a bug in a dependency, a decision you made and rejected alternatives for.
// Stripe's webhook can deliver events out of order under high load,
// so we ignore any event older than the one we've already processed
// for this subscription, rather than trusting webhook delivery order.
// See incident postmortem #482.
if (event.created < lastProcessedEventTimestamp) {
return;
}
Nothing about reading that if statement alone tells you why it exists. Without the comment, a future engineer — quite possibly me, again — looks at this six months later, concludes it looks like dead defensive code that can't possibly matter, and deletes it during a cleanup pass. Then webhooks start processing out of order again and nobody connects the regression to that deletion for a week. The comment is cheap insurance against exactly that failure mode, and it's the kind of context that genuinely cannot be inferred from the code no matter how well-named your variables are.
Structure is empathy made visible
Readability isn't only local, at the level of a single function — it's also about how a reader navigates the whole file or module. I try to write functions so that reading top to bottom tells a story at a consistent level of abstraction, rather than jumping between "here's the high-level flow" and "here's a low-level string-parsing detail" and back again within the same function.
Before:
async function checkoutOrder(cart: Cart) {
let total = 0;
for (const item of cart.items) {
total += item.price * item.quantity;
}
if (cart.promoCode) {
const promo = await db.query('SELECT * FROM promos WHERE code = ?', [cart.promoCode]);
if (promo && promo.expiresAt > new Date()) {
total = total * (1 - promo.discountPercent / 100);
}
}
const order = await db.query('INSERT INTO orders ...', [cart.userId, total]);
await emailService.send(cart.userId, 'order-confirmation', { total });
return order;
}
After, pulling the low-level details out into named functions so the top-level function reads like a summary:
async function checkoutOrder(cart: Cart): Promise {
const subtotal = calculateSubtotal(cart.items);
const total = await applyPromoCode(subtotal, cart.promoCode);
const order = await createOrder(cart.userId, total);
await sendOrderConfirmation(cart.userId, total);
return order;
}
Nothing here is cleverer than the original — it's the same logic, relocated. But the second version lets a reader understand the checkout flow in about four seconds without caring how the promo code discount is calculated, and lets someone debugging a promo code issue jump straight into applyPromoCode without wading through order-creation logic that's irrelevant to their bug. That's the actual payoff of decomposition: it lets a reader choose their own level of detail instead of forcing everyone through every line every time.
The next person is not you, even when it is
The thing I keep coming back to is that "readable code" is really a proxy for "code that respects the reader's limited context." Whoever opens this file next — a new hire on their second week, a teammate debugging a production incident at 11pm, or you in eighteen months with none of today's context left in your head — doesn't have the mental model you're currently holding. They didn't sit in the meeting where the business rule got decided. They don't remember which edge case that weird conditional is guarding against. Every choice you make in naming, structuring, and commenting either gives them a shortcut back to that context or forces them to reconstruct it from scratch, usually under time pressure.
Code review is where this either gets reinforced or quietly abandoned as a team norm. I've started asking a specific question in reviews that's more useful than "does this work": "if I'd never seen this feature before, could I understand what this function does from its name and signature alone?" It's a small reframe, but it shifts review conversations away from style preferences and toward genuine comprehension, which is the thing that actually matters six months later when nobody remembers the original PR discussion, the Slack thread has scrolled into oblivion, and all that's left is the code itself, doing the explaining on its own.
Readability compounds the same way debt does, just in the other direction
What I've come to appreciate most about investing in readability is that it compounds. A well-named function makes the function that calls it easier to read, which makes the file easier to skim, which makes the whole module easier to onboard into, and each of those gains stacks on the last one rather than existing in isolation. The inverse is just as true and just as compounding — a handful of unclear names in a foundational utility file quietly taxes every single caller for as long as that file exists, which in a long-lived codebase can be years, touched by dozens of people who never chose that name and have no idea why it's confusing, just that it is. I've started treating a rename or a small structural cleanup as one of the highest-leverage changes I can make in a codebase precisely because of that compounding effect, even when it produces a diff with zero behavioral change and therefore looks, on the surface, like it accomplished nothing at all.
Related Posts
Sponsor Our Newsletter
Reach thousands of developers who are actively evaluating AI tools, MCP servers, and dev infrastructure. Our weekly newsletter goes to engaged technical decision-makers.
All sponsored content is clearly labeled per our editorial policy.