Skip to main content
Start your own AI-powered blog — freeGet started →

How I Document Code Without Hating It

How I Document Code Without Hating It
Photo by Antonio Batinić on pexels

How I Document Code Without Hating It

I used to think I hated documentation. I'd put it off, do it grudgingly at the end, write a paragraph of obvious nonsense, and feel a small resentment toward the whole concept.

It took me an embarrassingly long time to realize I didn't hate documentation. I hated writing bad documentation — the useless, obligatory kind that helps no one and bores everyone, including the author.

Once I figured out what to write and what to skip, the resentment vanished. Now I document things and, weird as it sounds, sometimes enjoy it. Here's the shift.

Quick Answer

I stopped hating documentation when I stopped explaining what the code does and started explaining why it does it. The code already shows the what. The why — the decisions, trade-offs, and traps — is the part that's invisible and genuinely worth writing down.

The short version:

  • Don't document what the code already says. That's noise.
  • Document the why: decisions, trade-offs, and the surprises.
  • Write the doc you wish you'd found at 2 a.m. while debugging.

Most documentation is worthless on purpose

Let me show you the kind of documentation that made me hate documentation:

code
// This function adds two numbers
function add(a, b) {
  return a + b;
}

That comment is worse than nothing. It takes up space, it can drift out of sync with the code, and it tells the reader something the code already screamed at them. It's pure ritual.

A huge amount of documentation is exactly this: a restatement of the code in slightly clumsier English. It exists because someone was told "write documentation," so they dutifully described what the next line plainly does.

That's the trap. If your documentation just narrates the code, the code is already a better version of that documentation. Self-explanatory code needs no comment explaining it's self-explanatory. The realization that freed me was simple: most of what I was forcing myself to write should never have been written at all. Knowing what not to write down is its own kind of maturity, and it's a thread running through the brutal truth about becoming a senior developer.

A notebook and laptop with handwritten notes beside code Photo by Lukas Blazek on Pexels

The only documentation worth writing: the why

Code is excellent at expressing what and how. Read it carefully and you can see exactly what happens. What code can never express is why — and the why is where all the real value hides.

Why did you choose this approach over the obvious one? Why is there a strange-looking check on line forty that, if you remove it, breaks everything in a way nobody will guess? Why does this function exist at all? Why this weird order of operations?

None of that is visible in the code. It lived in your head the day you wrote it, and your head will not remember in six months. That is exactly what documentation is for.

The kinds of "why" worth capturing:

  • Decisions and their alternatives. "We use this approach instead of the obvious one because the obvious one fails under concurrent load." Now the next person won't innocently "simplify" it back into a bug.
  • The non-obvious and the dangerous. "This must run before that, or the cache serves stale data." The traps that would otherwise be re-discovered the hard way.
  • Context the code can't hold. Why this thing exists, what real-world rule it encodes, the historical reason it's shaped this way.

This documentation is a gift to the future — usually to future you, who will arrive confused and grateful. The naming instinct I describe in why naming things is the hardest part of coding does half this job for free: clear names mean you only have to document the genuinely surprising parts. Even canonical engineering references like the MDN Web Docs earn their keep by explaining why a behavior exists, not by restating syntax.

Good code answers "what." Good comments answer "why." If a comment answers "what," delete it and let the code speak.

Match the doc to its job

Not all documentation is the same thing, and conflating them is part of why it feels miserable. I think in a few clear buckets, each with a different job:

TypeQuestion it answersWhere it lives
Inline commentWhy is this line weird?Next to the code
Function docHow do I use this without reading it?Above the function
READMEHow do I run and contribute to this?Repo root
Decision recordWhy did we build it this way?A docs folder

Knowing which one you're writing makes it easy, because each has a tight, obvious scope. The dread comes from a vague mandate to "document the code" with no sense of audience or purpose. Pick the bucket, answer its one question, stop.

The function doc deserves special mention. Its entire job is to let someone use your function without reading the body. So it describes the inputs, the output, and any surprising behavior — the contract, not the implementation. Write that and you've saved every future caller a trip into your guts.

Write it for the person debugging at 2 a.m.

The mental trick that turned documentation from chore to craft: I picture a specific reader. It's someone — often me — staring at this code at 2 a.m., a production incident burning, trying to understand what's happening and why.

What would help that person? Not "this function adds two numbers." They'd want to know the trap. The assumption. The reason this looks wrong but isn't. The thing that, if they change it, will make everything worse.

When I write for that exhausted, stressed reader, the documentation writes itself, because suddenly I know exactly what matters. I'm not performing thoroughness. I'm leaving a note for a friend in trouble.

A few habits that flow from this:

  1. Document at the moment of decision. When I choose a non-obvious approach, I write the why right then, while the alternatives are fresh. Reconstructing it later is the painful, resented version.
  2. Comment the surprises, not the routine. If a line would make a competent reader pause and go "huh?", it gets a comment. If it wouldn't, it doesn't.
  3. Let tools handle the boilerplate. Modern developer tools and AI assistants are great at generating the mechanical parts — function signatures, parameter lists, usage examples. I let automation draft those, then I add the one thing a machine can't know: why. That division keeps the tedious part cheap and the valuable part mine.

A clean workspace with a laptop showing organized notes Photo by Godfrey Atima on Pexels

What changed when I stopped over-documenting

The biggest surprise: writing less documentation made the documentation I did write far more valuable.

When every other line had a pointless comment, the rare important comment drowned in the noise. Once I stripped the obvious stuff, what remained was all signal. A comment now means "pay attention, something non-obvious is here" — and people actually read them, because they've learned my comments are never wasted.

My code got cleaner too. The push to make code self-explanatory — so it needs no "what" comments — is just the push to write clear code. Good naming, small functions, obvious structure. Aiming to document less forced me to write code that deserved less documentation.

If you'd like more small shifts that turn dreaded chores into craft, it's worth following along with the rest of these notes.

The bottom line

I never hated documentation. I hated writing the useless kind, the kind that narrates code that can already speak for itself. The moment I switched from documenting what to documenting why, the chore became a craft.

Skip what the code already says. Capture the decisions, the trade-offs, and the traps. Write for the tired person debugging at 2 a.m., because one day that person is you.

Next time you reach for a comment, ask whether you're explaining what the code does or why it does it. If it's the what, let the code talk. If it's the why, you've just found the one note worth leaving.

Key Takeaways

  • Document the why (decisions, trade-offs, traps) instead of the what (code already shows this). Example: "We use this approach instead of the obvious one because it handles concurrent load" saves future debugging time.
  • Delete comments that restate the code (e.g., // This function adds two numbers). They add noise, risk drift, and waste attention—signal comes from explaining surprises, not routine.
  • Match documentation to its purpose: inline comments for why this line is weird, function docs for how to use this without reading it, READMEs for how to run/contribute, and decision records for why we built it this way.
  • Write for the exhausted 2 a.m. debugger. Ask: What would help me right now if I were fixing this in production? Focus on traps, assumptions, and non-obvious context—skip the obvious.
  • Document at the moment of decision. Capture the why when alternatives are fresh; reconstructing it later is painful and often inaccurate. Example: Add a comment when choosing a non-obvious algorithm.
  • Let tools handle boilerplate (signatures, usage examples) and reserve your effort for the why—the part only you can explain. This keeps documentation valuable without becoming a chore.

Frequently Asked Questions

Doesn't less documentation hurt new team members?

The opposite, if you're documenting the right things. New members aren't helped by comments restating obvious code — they can read code. They're helped enormously by the why: the decisions, the traps, the context. Concentrated, meaningful documentation onboards far better than a fog of noise.

How do I document without it going stale?

Stale documentation usually comes from documenting the what, which changes every time the code does. The why — decisions and trade-offs — is far more stable; it rarely changes even when the implementation is rewritten. Documenting why instead of what is itself the best defense against staleness.

Should I use AI to write my documentation?

Use it for the mechanical scaffolding — signatures, parameter descriptions, usage examples it can infer from the code. But the genuinely valuable part, the why, lives only in your head; no tool can recover a decision it never witnessed. Let automation draft the boilerplate and reserve your effort for the reasoning.

What about projects with no documentation at all?

Don't try to document everything at once — that's the path back to hating it. Add a why-comment whenever you touch a confusing piece, and write a decision record the next time you make a real architectural call. Let it accrete from real moments, the same way good tests do.

A
Assisters

2 followers

AI assistants platform by Misar AI. Building the future of AI-powered automation.

Comments

Sign in to join the conversation

No comments yet. Be the first to share your thoughts!

More from Assisters

Recommended for you