Documentation is Code for Humans
Most developers ignore documentation because authors treat it like marketing instead of a technical specification.
By git11 Engineering · Sat Mar 21 2026 · 6 min read
A developer with a terminal open has a high cognitive load and low patience. If they reach for your documentation, they are already stuck. You have roughly thirty seconds to prove that your text will solve their immediate problem before they go back to grep or git log.
Optimize for Grep
Developers do not read documentation linearly. They treat your README.md like a searchable log file. They hunt for specific symbols, error messages, or configuration keys. If your key information is buried inside a five-sentence paragraph, it is invisible.
Use short, punchy paragraphs. Keep sentences under 20 words. Use fixed-width font for every variable, file path, and command. This makes the important parts of the text stand out visually when a user scrolls through a page.
Structure your pages around nouns and verbs. Use headings like Authentication or Rotating API Keys instead of Getting Started with Security. Specificity reduces the time spent searching. If a user cannot find what they need in two CMD+F attempts, your documentation has failed.
The Three-Tier Structure
Effective documentation must serve three distinct mental models. Every repository requires these three files at minimum:
README.md: The immediate entry point for installation and high-level purpose. 2.
CONTRIBUTING.md: The technical hurdles for setting up a local development environment. 3. ARCHITECTURE.md: The conceptual map of how the components interact.
Keep these files in the root directory. Do not hide them in a docs/ folder unless they are large enough to require sub-navigation. Proximity to the source code is the only way to ensure the documentation stays updated.
Code Examples First
Most developers skip the prose and copy the code blocks. Your code examples are your primary documentation. If the code is wrong, the text does not matter. Use a tool like markdown-doctest to ensure your examples actually run.
Avoid placeholders like your_api_key_here. Use realistic looking data that matches the expected format. If a parameter expects a UUID, provide a UUID string in the example. This allows the user to paste the code into their terminal to see the immediate failure or success.
- Provide the exact shell command to install dependencies.
- Show the full response body for API calls.
- Include the imports necessary to make the snippet work.
- Use comments within code blocks to explain non-obvious logic.
Eliminate Marketing Words
Adjectives are noise. Words like 'fast', 'simple', and 'powerful' provide no technical value. If your library is fast, provide a benchmark in a table. If it is simple, show a three-line code snippet.
Instead of saying 'this function is powerful', describe what it does. 'This function merges two JSON objects and resolves key conflicts using a Last-Write-Wins strategy.' This tells the developer exactly what to expect without the fluff.
Senior engineers value technical precision over enthusiasm. Write as if you are explaining the system to a peer during a high-stakes incident. You would not use marketing jargon during a production outage. Treat your reader with that same level of urgency.
Maintain the Delta
Documentation rot is a technical debt. When you change a function signature in src/utils.ts, you must update the corresponding README.md in the same pull request. If the PR does not include the documentation update, it is incomplete.
- Enforce documentation checks in your CI/CD pipeline.
- Use
docformatteror similar tools to maintain consistent styling. - Delete documentation for features that no longer exist.
- Link directly to the source code line if the logic is complex.
Old documentation is worse than no documentation. It leads developers down dead ends and creates frustration. If a feature is deprecated, add a visible warning at the top of the relevant section immediately.
Internal Architecture Maps
Developers need to know how data flows through your system. An ARCHITECTURE.md file should explain the 'Why' behind the 'How'. Describe why you chose a specific database or why a certain service communicates over NATS instead of HTTP.
Use Mermaid.js or simple ASCII diagrams for visual flow. A text-based diagram is version-controlled and searchable. It allows a new engineer to visualize the system without leaving the terminal.
List the external dependencies and why they are there. If you use redis for caching but postgres for state, say so. This prevents future developers from making architectural mistakes that violate the original design intent.
The Installation Test
Test your installation instructions on a clean machine. Use a fresh Docker container or a new cloud instance. Follow your README.md exactly, step by step. If you find yourself typing a command that is not in the guide, the guide is broken.
- Spin up a clean
ubuntu:22.04image. 2. Clone the repository.
- Run the setup script. 4. Execute the test suite.
If any step fails, fix the documentation. This process should be automated. A script that verifies the setup instructions ensures that your onboarding process never breaks as the project evolves.
Error Messages as Documentation
Every error message your software prints is a piece of documentation. Instead of printing Error: Invalid Input, print Error: The 'timeout' value must be an integer between 1 and 3600. Current value: -5.
Good error messages point the user back to the documentation. Include a URL or a specific command to fix the issue. This reduces the number of support tickets and GitHub issues your team has to handle.
- State what happened.
- State why it happened.
- State how to fix it.
- Provide a link to the relevant manual page.
Writing for the Lazy
Assume your reader is tired and distracted. They have fifteen Chrome tabs open and a deadline in two hours. They are not reading your prose to appreciate your writing style. They want to finish their task and go home.
Use bold text for the most important sentences. If a paragraph contains a critical warning, prefix it with IMPORTANT. Use bulleted lists to break up long sequences of information. The more whitespace you have, the easier the document is to scan.
Write in the active voice. Instead of 'The configuration can be modified in config.json', write 'Edit config.json to change the port'. This is shorter and clearer. It tells the user exactly what action to take.
Versioning Your Docs
Documentation must match the version of the software the user is running. If your main branch documentation describes features only found in v2.0.0-beta, users on v1.2.0 will be confused.
Use a documentation generator that supports versioning, like Docusaurus or MkDocs. Link the documentation version to the Git tag. This ensures that a developer looking at the docs for an older version of your package sees the correct information.
Write your documentation in the same repository as the code. Separate documentation repositories always fall out of sync. When they are in the same repo, changing the code and the docs happens in a single atomic commit.
Stop writing essays and start writing specifications.