The docs-as-code movement has transformed how teams write documentation. Instead of Word documents and Confluence pages, modern teams write technical docs in Markdown — versioned in Git, reviewed in pull requests, and deployed alongside code.

This guide covers best practices for writing technical documentation in Markdown, with ready-to-use templates for the most common document types.

Why Markdown for Technical Docs?

Version Control

Markdown files are plain text, making them perfect for Git:

git log --oneline docs/api-reference.md
# a1b2c3d Update authentication section
# d4e5f6g Add rate limiting documentation
# g7h8i9j Initial API reference

Every change is tracked, reviewable, and reversible.

Developer-Friendly

Developers already know Markdown from GitHub READMEs. No new tools to learn, no proprietary editors to install.

Portable

Markdown renders beautifully in:

  • GitHub / GitLab / Bitbucket
  • Static site generators (Docusaurus, MkDocs, Astro)
  • Note-taking apps (Obsidian, VS Code)
  • Mobile viewers (MerMD)

Code-First

Technical docs are full of code examples. Markdown’s fenced code blocks with syntax highlighting are purpose-built for this.

Document Type Templates

API Reference

# API Reference

Base URL: `https://api.example.com/v1`

## Authentication

All requests require a Bearer token:

\`\`\`bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://api.example.com/v1/users
\`\`\`

## Endpoints

### GET /users

Retrieve a list of users.

**Parameters:**

| Parameter | Type | Required | Description |
|:----------|:-----|:---------|:------------|
| `page` | integer | No | Page number (default: 1) |
| `limit` | integer | No | Items per page (default: 20, max: 100) |
| `role` | string | No | Filter by role: `admin`, `user`, `viewer` |

**Response:**

\`\`\`json
{
  "data": [
    {
      "id": "usr_123",
      "name": "Alice Smith",
      "email": "alice@example.com",
      "role": "admin",
      "created_at": "2026-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 142
  }
}
\`\`\`

**Status Codes:**

| Code | Description |
|:-----|:------------|
| 200 | Success |
| 401 | Unauthorized — invalid or missing token |
| 429 | Rate limited — too many requests |
| 500 | Internal server error |

### POST /users

Create a new user.

**Request Body:**

\`\`\`json
{
  "name": "Bob Johnson",
  "email": "bob@example.com",
  "role": "user"
}
\`\`\`

**Response:** `201 Created`

Setup / Installation Guide

# Getting Started

## Prerequisites

Before you begin, make sure you have:

- [ ] **Node.js** v18 or higher ([download](https://nodejs.org))
- [ ] **Git** v2.30+ ([download](https://git-scm.com))
- [ ] **Docker** (optional, for containerized deployment)

## Installation

### 1. Clone the Repository

\`\`\`bash
git clone https://github.com/org/project.git
cd project
\`\`\`

### 2. Install Dependencies

\`\`\`bash
npm install
\`\`\`

### 3. Configure Environment

Copy the example environment file:

\`\`\`bash
cp .env.example .env
\`\`\`

Edit `.env` with your settings:

\`\`\`bash
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=your-api-key-here
PORT=3000
\`\`\`

### 4. Run Database Migrations

\`\`\`bash
npm run db:migrate
\`\`\`

### 5. Start the Development Server

\`\`\`bash
npm run dev
\`\`\`

Open http://localhost:3000 in your browser.

## Verify Installation

Run the test suite to confirm everything works:

\`\`\`bash
npm test
\`\`\`

Expected output:
\`\`\`
✓ 142 tests passed
✓ 0 tests failed
\`\`\`

## Troubleshooting

### Port 3000 is already in use

\`\`\`bash
# Find what's using the port
lsof -i :3000

# Or use a different port
PORT=3001 npm run dev
\`\`\`

### Database connection refused

Make sure PostgreSQL is running:

\`\`\`bash
sudo systemctl status postgresql
\`\`\`

Architecture Document

# System Architecture

## Overview

The application follows a microservices architecture with
an API gateway, three core services, and a shared database layer.

```mermaid
graph TD
    A[Client App] --> B[API Gateway]
    B --> C[Auth Service]
    B --> D[User Service]
    B --> E[Payment Service]
    C --> F[(Auth DB)]
    D --> G[(User DB)]
    E --> H[(Payment DB)]
    E --> I[Stripe API]
```

## Components

### API Gateway
- **Technology:** Express.js / Node.js
- **Purpose:** Request routing, rate limiting, authentication
- **Port:** 3000

### Auth Service
- **Technology:** Go
- **Purpose:** JWT token generation, OAuth2 integration
- **Port:** 3001

### User Service
- **Technology:** Python / FastAPI
- **Purpose:** User CRUD, profile management
- **Port:** 3002

### Payment Service
- **Technology:** Node.js
- **Purpose:** Stripe integration, billing, invoices
- **Port:** 3003

## Data Flow

### User Registration

```mermaid
sequenceDiagram
    participant C as Client
    participant G as API Gateway
    participant A as Auth Service
    participant U as User Service

    C->>G: POST /register
    G->>U: Create user record
    U-->>G: User created (id: 123)
    G->>A: Generate JWT for user 123
    A-->>G: JWT token
    G-->>C: 201 Created + JWT
```

## Deployment

```mermaid
graph LR
    A[GitHub] -->|push| B[CI/CD]
    B -->|build| C[Docker Registry]
    C -->|deploy| D[Kubernetes]
    D --> E[Production]
```

Changelog

# Changelog

All notable changes to this project will be documented
in this file. Format based on
[Keep a Changelog](https://keepachangelog.com/).

## [2.3.0] — 2026-07-01

### Added
- Dark mode support across all pages
- Export to PDF functionality
- Keyboard shortcuts for navigation

### Changed
- Upgraded React from 18.x to 19.x
- Improved search performance by 3x
- Updated API rate limits (100 → 200 req/min)

### Fixed
- Login redirect loop on expired sessions
- CSV export timeout for large datasets
- Mobile layout overflow on tables

### Security
- Patched XSS vulnerability in comment rendering
- Updated dependencies with known CVEs

## [2.2.1] — 2026-06-15

### Fixed
- Hot fix for database connection pool exhaustion
- Corrected timezone handling in scheduled reports

## [2.2.0] — 2026-06-01

### Added
- Real-time notifications via WebSocket
- User activity dashboard
- Bulk import from CSV

Runbook / Incident Response

# Incident Response Runbook

## High CPU Alert (> 90%)

### Severity: P2
### On-Call Response Time: 15 minutes

### Diagnosis

1. Check which service is consuming CPU:

\`\`\`bash
kubectl top pods -n production
\`\`\`

2. Check for recent deployments:

\`\`\`bash
kubectl rollout history deployment/api-server -n production
\`\`\`

3. Check application logs:

\`\`\`bash
kubectl logs -f deployment/api-server -n production --tail=100
\`\`\`

### Common Causes

| Cause | Indicator | Fix |
|:------|:----------|:----|
| Traffic spike | Request count 5x normal | Scale up replicas |
| Memory leak | Gradual increase over hours | Restart pods |
| Bad query | Single pod at 100% | Kill query, add index |
| Infinite loop | CPU spike after deploy | Rollback |

### Mitigation

**Scale up (immediate relief):**

\`\`\`bash
kubectl scale deployment/api-server --replicas=10 -n production
\`\`\`

**Rollback (if caused by deploy):**

\`\`\`bash
kubectl rollout undo deployment/api-server -n production
\`\`\`

### Escalation
- If not resolved in 30 minutes → Page tech lead
- If customer-facing impact → Notify support team
- If data integrity risk → Page database team

Best Practices

1. Use a Consistent Structure

Every document should follow the same pattern:

Title → Overview → Details → Examples → Troubleshooting

2. Lead with the Most Important Information

Don’t bury the answer. Put the key command, endpoint, or instruction at the top — then explain why below.

3. Make Code Copy-Pasteable

Every code block should work when pasted directly. Include:

  • Full commands (not fragments)
  • Required flags and options
  • Expected output (so readers can verify)

4. Use Tables for Structured Data

Tables are dramatically more readable than lists for parameters, endpoints, error codes, and comparisons.

5. Include Diagrams

A Mermaid diagram explains architecture faster than five paragraphs of text. Use them for:

  • System architecture
  • Data flow
  • Sequence diagrams
  • Deployment pipelines

6. Keep It Updated

Outdated docs are worse than no docs. Treat documentation like code:

  • Review docs in PRs alongside code changes
  • Add doc updates to your team’s definition of done
  • Delete obsolete pages

7. Write for Scanning

Developers scan — they don’t read linearly:

  • Use descriptive headings
  • Bold key terms
  • Use bullet points over paragraphs
  • Add a table of contents for long docs

Reviewing Docs on Mobile

Technical documentation needs to be accessible everywhere — including on your phone during incidents, meetings, or code reviews. MerMD renders technical Markdown beautifully on Android:

  • Mermaid architecture diagrams — rendered natively
  • Syntax-highlighted code — 30+ languages
  • API reference tables — properly formatted
  • Cloud access — connect to GitHub, Google Drive
  • Offline reading — access runbooks during outages

Frequently Asked Questions

What’s the best tool for writing technical docs in Markdown? VS Code with the Markdown Preview Enhanced extension is the most popular choice. For team wikis, use Docusaurus or MkDocs.

Should I use Markdown or a wiki tool like Confluence? For developer-facing docs, Markdown in Git is superior — it’s versioned, reviewable, and portable. Confluence is better for non-technical team wikis.

How do I generate API docs from code? Tools like Swagger/OpenAPI generate API reference automatically. For supplementary docs (tutorials, guides), write them manually in Markdown.

Can I publish Markdown docs as a website? Yes! Use Docusaurus, MkDocs, VitePress, or Astro to turn your Markdown files into a beautiful documentation website.

Review Your Docs on Android

MerMD renders technical documentation beautifully — API references, architecture diagrams, code examples. Free on Google Play.

Download MerMD