Process
Documentation
Documentation is how knowledge lives beyond one person's brain. It's an investment that pays dividends for years. New team members onboard faster. Production issues get resolved quicker. Code remains maintainable even when the original developers move on. Yet documentation is often treated as an afterthought—something you do when you have time, which is never.
Documentation as Investment
Here's the mental shift: Documentation isn't overhead. It's an investment in your project's sustainability.
Consider the cost of a new developer joining without documentation. They spend 3 days asking questions. They misunderstand the architecture and make a change that breaks something. They ask "why does this code do this?" and no one knows because the original developer left 6 months ago. Documentation would have saved 20+ hours of productivity and prevented a production bug.
Or consider the cost of onboarding yourself back into code you wrote 18 months ago. You forgot why decisions were made. You spend an hour understanding something that would have taken 5 minutes with documentation.
Good documentation saves time at scale. It compounds over the project's lifetime.
Types of Documentation
Different types of knowledge need different documentation:
- Code comments: Explain the "why" of tricky code. Not what the code does (that's obvious from reading it), but why you did it that way. "We use a cache here because the database query is slow."
- README: The entry point for anyone new to the project. How to run it locally, what it does, who maintains it, key dependencies.
- API documentation: How to use your API. What endpoints exist, what parameters they take, what they return. Auto-generated from code is ideal.
- Architecture documentation: How the system fits together. What are the key components, how do they interact, what data flows where.
- Runbooks: How to handle operational tasks. How to deploy, how to scale the database, how to debug production issues.
- User guides: How to use the app, for users or admins.
- Decision records: Why major decisions were made. This is crucial for understanding why things are the way they are.
Every Project Needs This
At minimum, every project should have:
- README.md: What the project is, how to run it locally, how to contribute, key dependencies, links to other docs
- Setup guide: Step-by-step instructions for running the app on a fresh machine. Include dependencies, environment variables, database setup.
- Architecture overview: What are the major components, how do they talk to each other
- Deployment process: How to get code from your machine to production. What happens during a deploy, how to roll back
- Known issues: What's broken or has limitations. Better people learn from docs than from production disasters
Auto-Generated API Documentation
For APIs, hand-written documentation gets out of sync fast. A better approach is to generate documentation from the code itself.
Tools like Swagger/OpenAPI let developers annotate their code with metadata about endpoints. A generator then creates interactive documentation that's always accurate—you can even test API calls directly from the docs.
Example: A developer adds a few lines to document an endpoint:
- The endpoint path and method (POST /api/users)
- What parameters it takes and their types
- What it returns
- What errors it can throw
The documentation generator creates beautiful, interactive docs automatically. No manual sync needed.
Architecture Decision Records (ADRs)
One of the most valuable types of documentation is a record of why major decisions were made. This is what an ADR (Architecture Decision Record) is for.
Format (simple):
- Title: "Use PostgreSQL for the main database"
- Status: Accepted / Proposed / Superseded
- Context: Why were we making this decision? What problem does it solve?
- Decision: What we decided
- Consequences: What's good about this choice, what's difficult
Example ADR:
Title: Use Redis for caching
Context: Our API responses were slow because database queries took 500ms+. We need to reduce latency.
Decision: Add Redis as a caching layer between the API and database.
Consequences: Responses are faster (good), we now have another system to maintain (bad), we need to handle cache invalidation (complex).
ADRs answer the question "why does the architecture look like this?" Six months later, when someone asks "why don't we use Memcached instead of Redis?", you have the answer.
README Best Practices
A good README includes:
| Section | What to Include | Why It Matters |
|---|---|---|
| Project name & description | One sentence about what it does | Clarity. Someone should understand the project in 10 seconds. |
| Quick start | 5 steps to get it running: clone, install, configure, start, test | Lower the barrier to entry. People will actually set it up. |
| Prerequisites | Node 18+, PostgreSQL 12+, environment variables needed | Prevent setup failures. Tell people what they need before they start. |
| Directory structure | What's in src/, config/, tests/, etc. | Helps developers navigate the codebase quickly. |
| Key features | Bullet list of what the app does | Shows what's in scope. Prevents assumptions. |
| Architecture overview | Link to detailed architecture docs or a brief summary | Developers understand how pieces fit together. |
| How to contribute | Link to CONTRIBUTING.md, PR process, coding standards | Clarifies how new developers should work. |
| License | What license the code is under | Legal clarity, especially important for open source. |
| Contact | Who maintains this, how to report bugs or ask questions | Gives people a path to help when they need it. |
Writing for Future Developers (Including Future You)
When you write documentation, imagine reading it after 18 months of working on a different project. You've forgotten the details.
- Explain the why, not just the what. "We use this library because it handles X case that the alternatives don't" is more useful than just listing the library.
- Assume minimal context. Don't assume the reader knows about an earlier conversation or decision. Document it.
- Include examples. Code examples are worth thousands of words. Show how to use the API with a real example.
- Link to related docs. If this doc references another concept, link to it. Make navigation easy.
- Be specific, not vague. "Run npm install" is clearer than "install dependencies."
Documentation as Onboarding
The best way to onboard a new developer is to give them good documentation and let them follow it. Better yet, have them follow the docs while you watch—if they get stuck, that's a documentation bug. Fix it.
Good onboarding docs should let someone go from zero to working on their first story in 2–3 days. If it takes longer, there's friction in your documentation or setup.
The Staleness Problem
Documentation's biggest enemy is staleness. Code changes, but docs don't get updated. Six months later, the docs describe a system that no longer exists. Now they're worse than useless—they're actively misleading.
How to prevent staleness:
- Co-locate docs with code: Keep README and architecture docs in the Git repo, not a separate wiki. When code changes, the person making the change can update docs in the same PR.
- Require docs in PRs: If a PR changes how something works, it must update the docs. Make it part of the Definition of Done.
- Auto-generate what you can: API docs, test coverage reports, dependency lists—if it can be auto-generated, it won't go stale.
- Add a "last reviewed" date: If docs haven't been reviewed in a year, flag them as potentially stale. Assign someone to review.
- Link docs from the code: If a function's behavior is documented elsewhere, link to it in the code comment. If the docs get updated without the code being touched, you'll notice.
Documentation Tools
Where should you keep documentation?
- Git repo (README.md, markdown files): Closest to code, updated in PRs, versions with the code. Best for setup guides, architecture docs, ADRs.
- Confluence or Notion: Good for team documentation that's not code-specific. Easier to share with non-technical stakeholders. Risk of staleness because it's decoupled from code.
- GitHub Wiki: Markdown-based, integrated with GitHub. Good middle ground for project-specific docs.
- Storybook (for component libraries): Interactive documentation for UI components. Show how each component looks and works with live examples.
Most projects benefit from a layered approach: README and architecture docs in Git (version-controlled), API docs auto-generated, design docs in Notion for team collaboration, runbooks in Confluence for operations.
Documentation-Driven Development
Some teams write documentation before code. They write a design doc or RFC (Request for Comments) that describes what they're building and how. The team reviews it, suggests changes, and agrees on the direction. Then they build it.
Benefits:
- You catch design issues before coding
- Team alignment happens upfront, not mid-sprint
- The documentation exists from day one
It takes discipline, but for complex features, it's worth the time investment.
Balancing Effort
Documentation effort should scale with project size and complexity. A one-page startup MVP needs less documentation than a 500-person company's core platform. A simple CRUD app needs less than a real-time distributed system.
Minimum for all projects:
- README with setup instructions
- High-level architecture overview
- Deployment process
Add as the project grows:
- Detailed API documentation
- ADRs for major decisions
- Runbooks for operations
- User guides
Knowledge Transfer
Good documentation enables knowledge transfer. A developer can read how the system works without needing to sit with the architect for a week. A new team member can get up to speed. Someone can take over a project when the original developer leaves.
This is one of the most underrated aspects of documentation—it buys you freedom. Without documentation, you're stuck with the same people maintaining the same systems forever. With documentation, knowledge can flow to whoever needs it.
The next section covers Project Handover—the full process of transferring a project from development to production and beyond.