Writing Code for the Next Developer, Not Just the Machine
Code that works is the baseline. Code that the next developer can understand, extend, and debug in six months is the actual goal. These are the habits that make the difference.
Most code is written once and read many times. The machine runs it, but developers maintain it. Optimizing for the machine first is a mistake most programmers eventually grow out of. Here is what I have learned about writing code for the humans.
Name things honestly
The most valuable refactor is often just renaming. A function called getUser does not tell you if it fetches from a database, a cache, or an in-memory store. getUserFromCache, fetchUserFromDb, and findUser in session are each honest about what they do.
Honest names make code review faster, onboarding easier, and bugs more visible. A function called processData is a red flag. Process what data? Into what?
Prefer flat over clever
// Clever — impresses nobody maintaining it at 11pm
const result = data.reduce((acc, item) => ({...acc, [item.id]: item }), {});
// Readable — boring is good
const result: Record<string, Item> = {};
for (const item of data) {
result[item.id] = item;
}Clever code saves the writer time. Readable code saves every future reader time. The math always favors readability.
Comments explain why, not what
If a comment says what the code does, delete it — the code already says that. If a comment explains why a decision was made, the constraint it works around, or the bug it prevents, keep it. That context is priceless.
// Bad: describes what the code does
const sorted = items.sort((a, b) => a.date - b.date); // sort by date
// Good: explains why this specific approach is used
// Notion returns dates as Unix timestamps; JS sort needs numeric comparison
const sorted = items.sort((a, b) => a.date - b.date);Make illegal states unrepresentable
TypeScript's discriminated unions are the most powerful readability tool available. Instead of a object with a dozen optional fields where only some combinations are valid, model it as a union type where each variant is complete and self-describing.
The review heuristic
Before pushing code, I ask: if I came back to this in six months with no context, would I understand it? If the answer is no, I either simplify the code or add the context in a comment.
Readable code is not a style preference. It is a professional obligation. Future you — and everyone else on the team — will spend far more time reading your code than you spent writing it.