Self-Documenting Code vs. Comments: Lessons from Maintaining Large-Scale Codebases

Published: (January 11, 2026 at 05:31 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

The Danger of Stale Comments

The primary risk of comments is obsolescence. When code is refactored, developers often forget to update the associated comments. Over time those comments “rot,” becoming misleading and dangerous. Self‑documenting code avoids this problem because the logic itself is the source of truth—if the logic changes, the “documentation” (the code) must change by necessity.

Pillars of Self‑Documenting Code

1. Avoid Generic Abbreviations

Names should convey the what and how without needing a side‑note.

// Bad
const d = 86400; // seconds in a day

// Good
const SECONDS_IN_A_DAY = 86400;

2. Encapsulate Conditionals

Complex logic inside an if statement adds cognitive load. Move the logic into a well‑named variable or function.

// Bad
if (user.age > 18 && user.hasSubscription && !user.isBanned) {
  // …
}

// Good
const canAccessPremiumContent =
  user.isAdult && user.hasActivePlan && !user.isAccountFlagged;

if (canAccessPremiumContent) {
  // …
}

3. Use Strong Types as Living Documentation

Enums and interfaces replace “magic strings” and make valid options explicit.

// Dart example
enum OrderStatus { pending, shipped, delivered }
// Instead of passing a raw String for status, use OrderStatus.

When to Use Comments

Comments are valuable when the code cannot explain the context or why a decision was made. Typical scenarios include:

  • Workarounds – e.g., // Using a legacy loop here because the .map() polyfill fails in IE11.
  • Business Logic Why – e.g., // We trigger this sync twice to ensure the third‑party API acknowledges the handshake.
  • Critical Warnings – e.g., // CRITICAL: Do not change the order of these calls; it will cause a deadlock in the database.

Comparison: Pros and Cons

ApproachProsCons
Self‑Documenting• Always in sync with logic
• Reduces visual noise
• Forces better naming
• Cannot explain external “why”
• May lead to very long variable names
Comments• Explains non‑obvious business rules
• Provides IDE tooltips (e.g., JSDoc/DartDoc)
• High maintenance cost
• Prone to “rotting”
• Often hides “smelly” code

Documentation Hierarchy

  1. Level 1 – The Logic
    Write clean, modular code. If you need a comment to explain “Step 1, Step 2,” the function is probably too big—split it.

  2. Level 2 – The Types
    Use TypeScript, Dart, or similar type systems to define the shape of your data.

  3. Level 3 – The Doc‑String
    Add JSDoc/DartDoc for public APIs to surface information in IDE tooltips.

  4. Level 4 – The Why‑Comment
    Add a comment only when a developer would still ask, “Why on earth did we do it this way?” after reading the clean code.

Conclusion

The goal of a senior engineer isn’t to write no comments, but to write no redundant comments. Every line of text in your codebase should add value. When the code is clean, comments can focus on high‑level strategy rather than low‑level syntax, making the whole system easier to understand, maintain, and evolve.

Back to Blog

Related posts

Read more »

Designing APIs That Are Hard to Misuse

Most backend bugs don’t happen because developers are careless; they happen because APIs are easy to misuse. If an API allows the wrong thing, someone will even...

Your Codebase Needs OSHA

The Hidden Cost of a Messy Codebase I’ve never been able to function well in a messy space. It’s not about neatness—it’s something deeper. When things are scat...