Why Documentation Swells then Collapses
Most project wikis share the same arc: an eager volunteer pours hours into long-form guides, the first couple of pages are gold, and within three releases half of the content is stale. Deleting anything feels heretical, so the chassis keeps bloating. Soon engineers begin to ignore the whole collection and the cycle starts again.
The Lean Manifesto for Modern Code Docs
Treat documentation like code: short-lived branches, automated checks, and commits. The goal is not perfect prose; it is the smallest artifact that keeps the next developer un-stuck.
Part 1: Auto-Generated API Docs
Choose a generator, not a CMS
Static site generators such as Sphinx for Python, TypeDoc for TypeScript, and OpenAPI for REST keep the source of truth close to the code. They parse source files at build time and publish GitHub Pages without a database. Updates ride the same pull request that touches the endpoint, so drift is impossible unless CI is red.
Stub only what the compiler cannot see
Let type hints and examples fill method descriptions. Focus the hand-written lines on why the endpoint behaves unusually, not on its return type.
One job per comment
- Bus-factor risks (business formulas, regulatory edge cases)
- Performance gotchas (N+1 queries, exponential backoff)
- Known brittle coupling (third-party bug numbers with links)
Everything else belongs in test names or assertions.
Part 2: README as Landing Page
Limit yourself to eight sections
- One-sentence purpose
- Quick start (copy-paste command)
- Developer setup (OS quirks, ports)
- Folder map (table with one-liner per directory)
- Key scripts (how to run tests, lint, serve)
- Deployment pattern (Docker, npm publish, AMI)
- FAQ (solutions to common new-dev pain)
- License
Dump the rest in linked files
Create dedicated docs/
files only when the section exceeds three paragraphs. Git renders Markdown automatically; keep the barrier to entry at zero characters.
Part 3: Inline Documentation That Ages Gracefully
Write tests that read like sentences
A test called should_rate_items_below_target_weight_as_priority
is more resilient than a five-line comment above the function. When logic changes, the compiler forces the test to change along with it.
Favor self-documenting naming over apologetic wrappers
Rather than
// round up because the bank rounds up preventBankPenalty()
prefer
roundUpToNextCentMoney()
The method name stays relevant; business explanations can shift.
Use blame annotations instead of signatures
Tools such as git blame
and GitHub Edit
links already track authorship. Do not repeat names and dates in every file header; they become noise within a year.
Part 4: Lightweight Architecture Decision Records (ADRs)
One page per decision, 250 words max
Capture context, chosen option, consequences. When the decision is reversed, open a new ADR; the history becomes a chain instead of a patchwork edit war.
Filename pattern equals human grep
Store files at docs/adrs/YYYY-MM-DD-use-pgbouncer-for-pooling.md
. Alphabetic and chronological sort agree, making discovery frictionless.
Part 5: Code Review as Living Documentation
Summarize intent, not syntax, in the PR description
The description doubles as release notes. Your future teammate will search the merged pull request before the wiki when trying to understand the behavior difference between v2.3 and v2.4.
Pin epic comments with permalinks
Giant refactoring debates often hold design rationale. GitHub and GitLab let you link a specific comment line; stash that URL in the ADR so historical conversation remains one click away even after branch deletion.
Part 6: Tooling Cheatsheet
Language | Doc Generator | Live Reload | Deploy Hook |
---|---|---|---|
Python | Sphinx + MyST | sphinx-autobuild | GitHub Actions → Pages |
JavaScript | TypeDoc | typedoc --watch | Vercel PR comments |
Go | pkgsite | air | pkg.go.dev auto-sync |
OpenAPI | Redoc | @redocly/cli serve | Uploadspec on tag |
Part 7: Gradual Adoption for Existing Codebases
Start with stop-loss rules
- No new file lands without README root refresh.
- No public function ships without docstring example.
- No merged pull request exists without linked ADR for breaking change.
Timebox wiki gardening
Allocate one 45-minute session every sprint to delete or migrate legacy pages. If nobody misses the content after two sprints, it deserved to die.
Part 8: Outcome Metrics to Track
- Bus-factor question frequency: number of Slack pings that require tribal knowledge; aim downward.
- Time-to-first test failure: how long a new engineer needs to run
make test
; keep the instructions in README only. - Doc build warnings: keep the generator at zero so rot is visible.
Closing Thought
Documentation is not a deliverable; it is the cheapest critic you can hire. Make the critic tiny, keep her close to the code, and ship logic rather than lore.
Disclaimer: This article was generated by an AI assistant experienced in software engineering workflows and has been reviewed for technical accuracy. For official style guidance, consult each language or framework community.