“Lisez la doc.” Mais quelle doc ? Celle écrite il y a 2 ans et obsolète depuis 18 mois ? Voici comment créer une documentation que les développeurs vont réellement lire et maintenir.

Le problème : Doc obsolète ou inexistante

Symptômes classiques

# README.md (Last updated: 2021)

## Setup
Run `npm install`

(Mais le projet utilise pnpm depuis 2023)

Ou pire :

// Fichier: user.service.ts (500 lignes)
// Commentaire: Aucun
// README: "Le code se documente lui-même"

Résultat :

  • Nouveaux devs perdus
  • Bugs par incompréhension
  • Temps perdu à reverse-engineer

Principe : Code qui s’explique > Commentaires

Self-documenting code

Mauvais :

// ❌ Commentaire pour expliquer code obscur
// Check if user can buy (age > 18 and balance > price)
if (u.a > 18 && u.b > p) {
  // Process purchase
  db.insert({ uid: u.id, pid: p.id });
}

Bon :

// ✅ Code explicite, pas besoin de commentaire
function canUserPurchase(user: User, product: Product): boolean {
  const isAdult = user.age >= MINIMUM_AGE;
  const hasSufficientBalance = user.balance >= product.price;

  return isAdult && hasSufficientBalance;
}

if (canUserPurchase(user, product)) {
  createPurchase(user, product);
}

Règle : Si vous avez besoin d’un commentaire, refactorez d’abord.

Quand documenter (et quoi)

1. Le “Pourquoi”, pas le “Quoi”

Mauvais :

// ❌ Décrit CE QUE fait le code (évident)
// Incrémente counter
counter++;

Bon :

// ✅ Explique POURQUOI (pas évident)
// Workaround: API returns duplicates, dedupe client-side
// TODO: Fix in API (ticket #1234)
counter++;

2. Décisions non-évidentes

// ✅ Context important
// Using polling instead of WebSocket because:
// 1. Corporate firewalls block WS
// 2. 90% of users won't benefit (rarely updates)
// 3. Simpler implementation (no reconnect logic)
setInterval(checkUpdates, 30000);

3. Gotchas et edge cases

// ✅ Warning important
// IMPORTANT: Always call cleanup() after use
// Otherwise: memory leak (event listeners not removed)
class DataFetcher {
  // ...

  cleanup() {
    this.removeAllListeners();
  }
}

4. Algorithmes complexes

// ✅ Algorithme non-trivial
/**
 * Calculate shipping cost using tiered pricing:
 *
 * Weight (kg)  | Price (€/kg)
 * -------------|-------------
 * 0-5          | 2.50
 * 5-20         | 1.80
 * 20+          | 1.20
 *
 * Example: 15kg package
 * - First 5kg: 5 × 2.50 = 12.50
 * - Next 10kg: 10 × 1.80 = 18.00
 * - Total: 30.50€
 */
function calculateShippingCost(weightKg: number): number {
  // Implementation
}

Formats de documentation

1. README.md (Essentiel)

# Project Name

## What is this?
[1-2 sentences describing the project]

## Quick Start
```bash
npm install
npm run dev

Open http://localhost:3000

Architecture

[High-level diagram or link to docs/architecture.md]

Development

Setup

[Detailed setup steps]

Testing

npm test

Common Tasks

  • Add new endpoint: docs/guides/new-endpoint.md
  • Database migration: docs/guides/migrations.md

Deployment

[Link to deployment docs]

Get Help

  • Slack: #team-name
  • Issues: GitHub Issues
  • Docs: docs/

**Tester :** Chaque nouveau dev doit pouvoir suivre README et être productif en < 1h.

### 2. Architecture Decision Records (ADR)

```markdown
# ADR 005: Use PostgreSQL for main database

## Status
Accepted

## Context
We need to choose a database for our user data.
Expected: 100k users, complex relations.

## Decision
Use PostgreSQL 15.

## Consequences

### Positive
- ACID guarantees
- Rich SQL features
- Great tooling (pgAdmin, etc.)

### Negative
- Vertical scaling primarily
- More complex than MongoDB

## Alternatives Considered
- MongoDB: Rejected (need ACID)
- MySQL: Rejected (prefer PostgreSQL features)

3. API Documentation

OpenAPI / Swagger :

/users/{id}:
  get:
    summary: Get user by ID
    description: |
      Returns user data. Includes profile info and settings.

      **Rate limit:** 100 req/min per API key

      **Permissions:** Requires `users:read` scope
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        example: 123
    responses:
      '200':
        description: User found
        content:
          application/json:
            example:
              id: 123
              name: "Alice"
              email: "alice@example.com"
      '404':
        description: User not found

Auto-généré depuis code (idéal) :

/**
 * Get user by ID
 *
 * @route GET /api/users/:id
 * @param {number} id - User ID
 * @returns {User} User object
 * @throws {404} User not found
 * @example
 * GET /api/users/123
 * → { "id": 123, "name": "Alice" }
 */
router.get('/users/:id', async (req, res) => {
  // Implementation
});

// Tool: TypeDoc, JSDoc → Génère OpenAPI

4. Code comments (JSDoc/TSDoc)

/**
 * Calculate discount based on user tier and order total.
 *
 * Discount tiers:
 * - Standard: 0%
 * - Premium: 5%
 * - Enterprise: 10%
 *
 * Additional 5% if order > €1000
 *
 * @param user - User object with tier property
 * @param orderTotal - Total order amount in euros
 * @returns Discount amount in euros
 *
 * @example
 * calculateDiscount(premiumUser, 500)
 * // Returns: 25 (5% of 500)
 *
 * @example
 * calculateDiscount(premiumUser, 1200)
 * // Returns: 120 (10% of 1200: 5% tier + 5% volume)
 */
function calculateDiscount(user: User, orderTotal: number): number {
  let discountPercent = 0;

  // Tier discount
  if (user.tier === 'premium') discountPercent += 5;
  if (user.tier === 'enterprise') discountPercent += 10;

  // Volume discount
  if (orderTotal > 1000) discountPercent += 5;

  return orderTotal * (discountPercent / 100);
}

5. Guides (docs/)

docs/
├── architecture.md       # Vue d'ensemble
├── getting-started.md    # Setup détaillé
├── guides/
│   ├── adding-endpoint.md
│   ├── database-migrations.md
│   ├── testing.md
│   └── deployment.md
├── adr/                  # Architecture decisions
│   ├── 001-use-typescript.md
│   ├── 002-monorepo.md
│   └── 003-postgres.md
└── api/
    └── openapi.yaml      # API spec

Doc vivante : Rester à jour

Problème : Doc obsolète

# README (écrit 2021, jamais mis à jour)

Run: `npm start`

// Mais maintenant c'est `npm run dev`

Solution 1 : Doc dans code

// ✅ Doc = Code (toujours synchro)
const CONFIG = {
  /**
   * Server port. Default: 3000
   * Override with PORT env var
   */
  PORT: parseInt(process.env.PORT || '3000'),

  /**
   * Database URL
   * Format: postgresql://user:pass@host:port/db
   */
  DATABASE_URL: process.env.DATABASE_URL!,
};

Solution 2 : Tests as documentation

// ✅ Tests documentent behavior
describe('calculateDiscount', () => {
  it('gives 5% to premium users', () => {
    const user = { tier: 'premium' };
    expect(calculateDiscount(user, 100)).toBe(5);
  });

  it('gives additional 5% for orders > €1000', () => {
    const user = { tier: 'premium' };
    expect(calculateDiscount(user, 1200)).toBe(120); // 10% total
  });

  it('gives 0% to standard users on small orders', () => {
    const user = { tier: 'standard' };
    expect(calculateDiscount(user, 100)).toBe(0);
  });
});

Solution 3 : CI vérifie doc

# .github/workflows/docs.yml
name: Documentation

on: [pull_request]

jobs:
  check-docs:
    runs-on: ubuntu-latest
    steps:
      # Vérifier liens cassés
      - name: Check broken links
        run: markdown-link-check docs/**/*.md

      # Vérifier code examples compilent
      - name: Test code examples
        run: npm run test:docs-examples

      # Générer OpenAPI depuis code
      - name: Generate OpenAPI
        run: npm run generate:openapi

      # Fail si OpenAPI pas à jour
      - name: Check OpenAPI up-to-date
        run: git diff --exit-code docs/api/openapi.yaml

Solution 4 : Doc ownership

# CODEOWNERS
docs/**  @tech-lead
*.md     @tech-lead

# Force review doc changes

Outils

Documentation generators

TypeScript/JavaScript :

  • TypeDoc : Génère docs depuis TSDoc
  • JSDoc : Standard JavaScript
  • Docusaurus : Site docs (Facebook)

Python :

  • Sphinx : Standard Python
  • MkDocs : Markdown-based

API :

  • Swagger/OpenAPI : Standard API
  • Redoc : Beautiful API docs
  • Postman : API collection

Doc hosting

Open source :

  • GitHub Pages : Gratuit, facile
  • Read the Docs : Python projects
  • GitBook : Beautiful, mais payant

Internal :

  • Confluence : Enterprise wiki
  • Notion : Moderne, flexible
  • Custom : Docusaurus self-hosted

Exemples de bonne doc

Stripe API

✅ Clear examples
✅ Multiple languages
✅ Try in sandbox
✅ Error codes explained
✅ Rate limits documented

React docs

✅ Interactive examples
✅ Progressive (beginner → advanced)
✅ Search performant
✅ Dark mode
✅ Playground intégré

Tailwind CSS

✅ Visual examples
✅ Copy-paste ready
✅ Responsive preview
✅ Variants documented

Checklist : Doc quality

✅ README Quick Start < 5 minutes
✅ Architecture explained (diagram)
✅ Setup script automated
✅ API documented (OpenAPI)
✅ Common tasks have guides
✅ ADR for key decisions
✅ Code examples tested (CI)
✅ Links checked (CI)
✅ Updated < 3 months ago

Anti-patterns à éviter

1. Wall of text

❌ README with 2000 lines

✅ README with:
   - Quick start (50 lines)
   - Links to detailed guides

2. Doc au mauvais endroit

❌ "Read the Confluence page"
   (personne ne lit Confluence)

✅ Doc dans repo, proche du code

3. Commentaires qui disent rien

// ❌ Useless comments
// Get user
const user = getUser();

// Set name
user.name = name;

// Save user
saveUser(user);

// ✅ No comments needed (code clear)
const user = getUser();
user.name = name;
saveUser(user);

4. Doc jamais testée

❌ README écrit, jamais testé
   → Étapes manquantes, obsolète

✅ README testé à chaque nouveau dev
   → Toujours à jour

Cas réel : Open source library

Situation initiale

  • README : 50 lignes
  • Exemples : 0
  • API docs : “Read the code”
  • Adoption : 20 stars/mois

Amélioration

  1. README restructuré

    • Quick start
    • Examples visuels
    • API reference complète
  2. Documentation site (Docusaurus)

    • Guides step-by-step
    • Playground interactif
    • FAQ
  3. CI docs

    • Link checking
    • Examples tested
    • Auto-deploy

Résultats (6 mois)

  • Adoption : 20 → 300 stars/mois (+1400%)
  • Issues “How do I…” : -70%
  • Contributors : 3 → 25
  • Commentaire récurrent : “Best docs I’ve seen”

ROI doc : Investissement 2 semaines, impact énorme.

Conclusion

Documentation n’est pas optionnelle.

C’est un multiplier :

  • Onboarding 3x plus rapide
  • Bugs -50% (meilleure compréhension)
  • Contributions facilitées

Principes :

  1. Code self-documenting d’abord
  2. Documenter le “Pourquoi”
  3. Rester proche du code
  4. Tester et maintenir

Commencer petit :

  1. README Quick Start (1h)
  2. Guides essentiels (1 jour)
  3. CI check docs (2h)
  4. Iterate avec feedback

Et vous, état de votre doc ?