Language:English VersionChinese Version

Every engineer has experienced it: you discover a promising open source library, navigate to the documentation, and find a sparse README with an incomplete API reference and a “Getting Started” guide that assumes you already understand the system. You spend two hours reading source code to answer a question that should have taken two minutes. You move on to a competitor with better docs.

Documentation is not a nice-to-have. It is a competitive advantage — for open source projects competing for adoption, for companies competing for developers, and for internal teams competing for organizational attention and resources. Yet most engineering organizations treat documentation as an afterthought, a task to be completed after the “real work” is done. This article makes the case that documentation is the real work, and provides a practical framework for doing it well.

Why Most Documentation Fails

Before discussing how to write good documentation, it is worth understanding why most documentation is bad. The reasons are structural, not personal.

Wrong incentives: Engineers are rewarded for shipping features, not for writing docs. Performance reviews rarely mention documentation quality. Promotion criteria focus on technical complexity and impact, which documentation work struggles to demonstrate.

Wrong timing: Documentation is typically written after implementation, when the engineer’s understanding is at its peak but their motivation is at its lowest. The feature is shipped, the PR is merged, and documenting what they just built feels like busywork.

Wrong audience model: Engineers write documentation for people who already understand the system — themselves and their teammates. They skip foundational concepts, assume context that new readers do not have, and focus on the “what” rather than the “why.”

No ownership: Documentation that everyone owns, no one maintains. Without clear ownership and maintenance processes, docs decay rapidly. Within months of a major refactor, large portions of the documentation are outdated or actively misleading.

Wrong format: Many organizations default to wikis or Google Docs, which are disconnected from the codebase. Documentation that lives separately from code inevitably diverges from it.

Documentation-as-Code

The documentation-as-code approach treats documentation with the same rigor as source code: it lives in version control, goes through code review, is tested by CI, and is deployed automatically. This is not just an organizational preference — it fundamentally changes the relationship between code and documentation.

# Documentation lives alongside code
project/
  src/
    auth/
      login.ts
      login.test.ts
    api/
      users.ts
      users.test.ts
  docs/
    getting-started.md
    guides/
      authentication.md
      api-reference.md
    reference/
      configuration.md
  docusaurus.config.js
  package.json

When documentation lives in the same repository as code, several things happen naturally. Pull requests that change behavior include documentation updates — reviewers can see both changes in the same diff. Documentation is versioned alongside releases. Broken links and outdated references can be caught by CI. And the barrier to updating docs is the same as the barrier to updating code — a pull request.

The practical implementation is straightforward: documentation is written in Markdown (or MDX), stored in the repository, built by a static site generator, and deployed alongside the application. Changes to documentation go through the same review process as code changes.

The Diataxis Framework

The single most impactful improvement most organizations can make to their documentation is adopting the Diataxis framework, created by Daniele Procida. Diataxis identifies four distinct types of documentation, each serving a different purpose and requiring a different approach.

Tutorials: Learning-Oriented

Tutorials are lessons that take the reader through a series of steps to complete a project. They are learning-oriented — the goal is not to accomplish a task, but to learn by doing. A good tutorial is like a cooking class: the student follows along and ends up with a working result, gaining understanding along the way.

Key principles for tutorials:

  • The reader should achieve something meaningful by the end
  • Every step should work — test your tutorials regularly
  • Do not explain everything — focus on doing, not understanding
  • Start with the simplest possible example and build complexity gradually
## Tutorial: Building Your First API Endpoint

In this tutorial, you will create a REST API endpoint that stores
and retrieves user profiles. By the end, you will have a working
API running locally that you can test with curl.

### Prerequisites
- Node.js 20 or later installed
- A text editor

### Step 1: Create the Project

Create a new directory and initialize the project:

```bash
mkdir my-api && cd my-api
npm init -y
npm install express
```

### Step 2: Create the Server

Create a file called `server.js` with the following content:

```javascript
const express = require("express");
const app = express();

app.use(express.json());

const users = new Map();

app.post("/users", (req, res) => {
  const { name, email } = req.body;
  const id = crypto.randomUUID();
  users.set(id, { id, name, email });
  res.status(201).json(users.get(id));
});

app.get("/users/:id", (req, res) => {
  const user = users.get(req.params.id);
  if (!user) return res.status(404).json({ error: "Not found" });
  res.json(user);
});

app.listen(3000, () => console.log("Running on port 3000"));
```

How-To Guides: Task-Oriented

How-to guides are recipes for accomplishing specific tasks. Unlike tutorials, they assume the reader has foundational knowledge and needs to solve a particular problem. A how-to guide is like a recipe in a cookbook — it assumes you know how to cook and tells you how to make a specific dish.

Key principles for how-to guides:

  • Title should describe the problem being solved: “How to configure SSO with SAML”
  • Assume competence — do not re-explain basics
  • Focus on the specific task — do not wander into explanations
  • Provide the complete solution, including edge cases

Reference: Information-Oriented

Reference documentation describes the system as it is — APIs, configuration options, CLI flags, error codes. It is information-oriented, meant to be consulted rather than read. A good reference is like a dictionary: comprehensive, accurate, and consistently structured.

Key principles for reference documentation:

  • Be comprehensive — every public API, every configuration option, every error code
  • Be consistent — use the same structure for every entry
  • Be accurate — reference docs that disagree with the actual behavior are worse than no docs
  • Auto-generate where possible — API references generated from code comments stay in sync

Explanation: Understanding-Oriented

Explanations are discussions that help the reader understand concepts, make connections, and build mental models. They are understanding-oriented — they answer “why” questions. A good explanation is like a magazine article about cooking: it discusses techniques, history, and principles without telling you to do anything specific.

Key principles for explanations:

  • Discuss the “why” — design decisions, tradeoffs, alternatives considered
  • Provide context — how does this fit into the bigger picture?
  • Use analogies and examples to build intuition
  • It is acceptable to have opinions — explain why the system works the way it does

API Documentation Best Practices

API documentation deserves special attention because APIs are the primary interface through which developers interact with your system. Bad API docs are a direct tax on developer productivity.

Start with OpenAPI

Every REST API should have an OpenAPI (formerly Swagger) specification. This is the single source of truth for the API contract. From this specification, you can generate interactive documentation, client libraries, mock servers, and test suites.

# openapi.yaml
openapi: 3.1.0
info:
  title: User Management API
  version: 2.1.0
  description: |
    API for managing user accounts and profiles.
    All endpoints require Bearer token authentication.

paths:
  /users:
    post:
      summary: Create a new user
      description: |
        Creates a new user account. The email must be unique
        across all accounts in the organization.
      operationId: createUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
            example:
              name: "Jane Smith"
              email: "jane@example.com"
              role: "editor"
      responses:
        "201":
          description: User created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "409":
          description: Email already exists
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                code: "EMAIL_EXISTS"
                message: "A user with this email already exists"

Every Endpoint Needs Examples

The single most valuable addition to any API documentation is a working example for every endpoint. Not schema descriptions — actual request and response bodies that a developer can copy and paste. Include examples for success cases, common error cases, and edge cases.

Document the Errors

Error documentation is where most API docs fall short. Every API returns errors, and developers spend disproportionate time debugging them. Document every error code, what causes it, and how to resolve it. The developer who encounters an error should be able to find the solution in your docs within 30 seconds.

Documentation Tooling

The documentation tooling landscape has matured significantly. The best tools combine developer-friendly authoring experiences with polished output.

Mintlify

Mintlify has emerged as a leading documentation platform for developer-focused companies. It provides a beautiful default design, built-in API reference generation from OpenAPI specs, search, analytics, and AI-powered features. Mintlify uses MDX (Markdown with JSX), allowing interactive components within documentation pages. Its “suggest edits” feature and built-in feedback mechanisms help identify documentation gaps.

Docusaurus

Docusaurus, from Meta, remains the most popular open-source documentation framework. It is React-based, supports versioning, internationalization, and a rich plugin ecosystem. Docusaurus is the default choice for open source projects — its flexibility and zero cost make it accessible to projects of any size. The tradeoff is that it requires more configuration and design work than hosted alternatives.

Starlight

Starlight, built on Astro, is the newest serious contender. It offers excellent performance (static HTML by default, with JavaScript only when needed), built-in search, automatic navigation generation, and a clean default theme. Starlight is particularly good for projects that want great docs without committing to the React ecosystem.

// astro.config.mjs - Starlight configuration
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";

export default defineConfig({
  integrations: [
    starlight({
      title: "My Project Docs",
      social: {
        github: "https://github.com/myorg/myproject",
      },
      sidebar: [
        {
          label: "Getting Started",
          items: [
            { label: "Introduction", link: "/getting-started/intro" },
            { label: "Installation", link: "/getting-started/install" },
            { label: "Quick Start", link: "/getting-started/quickstart" },
          ],
        },
        {
          label: "Guides",
          autogenerate: { directory: "guides" },
        },
        {
          label: "API Reference",
          autogenerate: { directory: "reference" },
        },
      ],
    }),
  ],
});

Measuring Documentation Quality

You cannot improve what you do not measure. Documentation quality metrics fall into several categories.

Coverage metrics: What percentage of public APIs are documented? What percentage of features have tutorials or how-to guides? Are error codes documented? Coverage can be partially automated — scripts can compare API surface to documentation entries.

Freshness metrics: When was each page last updated? How many pages have not been updated since the last major release? Stale documentation is actively harmful — it is worse than no documentation because it misleads.

Usage metrics: Which pages are most visited? What are people searching for? Where do they leave the docs (indicating they did not find what they needed)? Tools like Mintlify and Docusaurus provide built-in analytics.

Feedback metrics: Add “Was this helpful?” widgets to every page. Track the ratio of positive to negative feedback. Follow up on negative feedback to identify specific gaps. These simple widgets generate surprisingly actionable data.

Support correlation: Track how many support tickets reference documentation — both “I could not find it in the docs” and “The docs were wrong.” A decrease in documentation-related support tickets is a direct measure of documentation improvement.

Creating a Documentation Culture

Tools and frameworks are necessary but not sufficient. Sustaining high-quality documentation requires a cultural shift.

Make it a first-class artifact: Documentation should be a required deliverable for every feature, not an optional follow-up. Pull requests that add features without documentation should not be approved. This needs to be a team norm enforced through code review.

Assign ownership: Every section of documentation should have a named owner. When a service is handed off, documentation ownership is explicitly transferred. Ownerless documentation decays.

Recognize the work: Include documentation contributions in performance reviews, sprint retrospectives, and team celebrations. If writing docs is invisible work, people will stop doing it.

Lower the barrier: Make it as easy as possible to update documentation. One-click edit links, templates for common doc types, and clear contribution guidelines reduce friction. Every unnecessary step in the doc contribution process is a reason for someone to not bother.

Schedule maintenance: Allocate regular time for documentation review and updates. Some teams designate a rotating “docs sheriff” who spends one day per sprint reviewing and updating documentation. Others schedule quarterly documentation sprints. The mechanism matters less than the commitment.

Examples of Great Documentation

Learning from the best is instructive. Several projects set the standard for developer documentation.

Stripe is widely regarded as having the best API documentation in the industry. Every endpoint has runnable examples in multiple languages. Error messages link directly to relevant documentation. The onboarding experience takes a developer from zero to first API call in under five minutes.

Anthropic offers clear, well-organized API documentation with practical examples, detailed guides on prompt engineering, and transparent explanations of model capabilities and limitations. The documentation balances technical precision with accessibility.

Tailwind CSS demonstrates how reference documentation can be both comprehensive and beautifully designed. Every utility class is documented with visual examples, and the search experience is exceptionally fast.

Rust has “The Rust Programming Language” (often called “The Book”), which is widely considered one of the best programming language tutorials ever written. It takes the reader from first principles to advanced concepts in a carefully structured progression.

Django was one of the earliest projects to take documentation seriously, and its docs remain a gold standard. The clear separation between tutorials, how-to guides, reference, and explanation predates the Diataxis framework — in fact, it inspired it.

Documentation as Competitive Advantage

The evidence is clear: well-documented projects and products win. In open source, documentation quality is the strongest predictor of adoption after core functionality. In enterprise software, documentation quality directly impacts time-to-value and support costs. In internal platforms, documentation determines whether teams self-serve or file tickets.

The organizations that treat documentation as a first-class engineering artifact — giving it the same attention, tooling, and respect as code — consistently outperform those that treat it as an afterthought. Documentation is not overhead. It is leverage. Every hour invested in good documentation saves ten hours of confused developers, misdirected support tickets, and abandoned evaluations.

Start with the Diataxis framework. Adopt documentation-as-code. Measure quality. Build the culture. Your documentation is your product’s first impression, its ongoing user experience, and its most scalable form of support. Make it worthy of the engineering it represents.

By Michael Sun

Founder and Editor-in-Chief of NovVista. Software engineer with hands-on experience in cloud infrastructure, full-stack development, and DevOps. Writes about AI tools, developer workflows, server architecture, and the practical side of technology. Based in China.

Leave a Reply

Your email address will not be published. Required fields are marked *