| name | technical-documentation |
| description | Use when writing a README, documenting an API with OpenAPI, drafting a runbook for on-call engineers, authoring a technical spec or ADR, or setting up docs-as-code with auto-deploy to GitHub Pages. |
Technical Documentation
Good technical documentation reduces onboarding time, prevents repeated questions, and makes systems maintainable by people who didn't build them.
When to Activate
- Writing a README for a new project or service
- Documenting an API with OpenAPI/Swagger
- Writing a runbook for an on-call engineer
- Creating an onboarding guide for a team
- Documenting a significant technical decision (ADR)
- Setting up documentation-as-code with auto-deploy to GitHub Pages
README Structure
A README is the front door to your project — it answers "what is this and how do I use it?" in under 5 minutes.
# service-name
[](...)
[](...)
One-sentence description of what this service does.
## Prerequisites
- Python 3.12+ / Node.js 20+ / Go 1.22+
- Docker 24+
- PostgreSQL 16 (or `docker compose up db`)
## Quickstart
\```bash
git clone https://github.com/org/service-name
cd service-name
cp .env.example .env # fill in required values
docker compose up -d db # start dependencies
make install # install dependencies
make dev # start dev server on :8000
\```
## Configuration
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DATABASE_URL` | Yes | — | PostgreSQL connection string |
| `JWT_SECRET` | Yes | — | 32-byte secret for JWT signing |
| `LOG_LEVEL` | No | `INFO` | Log verbosity (DEBUG/INFO/WARN/ERROR) |
| `PORT` | No | `8000` | HTTP server port |
## Development
\```bash
make test # run unit + integration tests
make lint # run linters
make typecheck # run type checker
make build # build production artifact
\```
See [docs/development.md](docs/development.md) for detailed setup, running locally, and debugging.
## Deployment
This service is deployed via GitHub Actions. See [docs/deployment.md](docs/deployment.md).
## Contributing
1. Fork the repo and create a branch: `feat/your-feature`
2. Make changes, write tests
3. Open a PR — the CI must be green before review
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
## License
MIT — see [LICENSE](LICENSE)
README Anti-Patterns
- Wall of text with no headings — add structure
- "Works on my machine" setup steps — use Docker or make targets
- Outdated screenshots — use text commands instead
- Missing prerequisites — list every external dependency
- No copy-paste quickstart — someone must be able to run it in 3 commands
OpenAPI / Swagger
OpenAPI 3.x is the standard for documenting REST APIs. Write it by hand (spec-first) or generate from code annotations.
Basic Structure
openapi: 3.1.0
info:
title: Payment Service API
version: 1.0.0
description: |
Processes payments and manages payment methods.
All endpoints require a Bearer token in the `Authorization` header.
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging-api.example.com/v1
description: Staging
security:
- BearerAuth: []
paths:
/payments:
post:
operationId: createPayment
summary: Create a payment
tags: [Payments]
requestBody:
required: true
content:
application/json:
schema:
[]
[, , ]
[, , ]
[, , ]
[, ]
$ref Reuse Rules
- Define all reusable schemas in
components/schemas
- Define reusable responses in
components/responses
- Define reusable parameters in
components/parameters
- Never duplicate a schema — use
$ref everywhere it appears
Tooling
| Tool | Purpose |
|---|
| Swagger UI | Interactive API browser, served locally or hosted |
| Redoc | Clean read-only API docs, good for public docs |
| Stoplight Elements | Embeddable, modern OpenAPI renderer |
openapi-generator | Generate client SDKs from spec |
prism | Mock server from OpenAPI spec |
Runbook Writing
See incident-response skill for the full runbook template. Key principles:
- Write for the 3am engineer — no tribal knowledge, no assumed context
- Number every step — so the engineer can say "I'm stuck on step 4"
- Include expected output — show what success looks like for each step
- Copy-paste commands — no
<REPLACE_ME> placeholders in commands
- Decision branches — "if X, do Y; otherwise do Z"
- Keep runbooks current — update after every incident that required improvisation
Architecture Decision Records (ADRs)
ADRs document why a significant decision was made — not just what was decided. Future engineers need context, not just conclusions.
See system-design skill for the full ADR template and lifecycle.
When to Write an ADR
- Choosing a database or message queue technology
- Adopting a new framework or library with significant lock-in
- Changing authentication mechanism
- Moving from monolith to microservices (or vice versa)
- Adopting a new infrastructure pattern (Kubernetes, serverless)
- Any decision that would surprise a new team member
Conventions
docs/
└── adr/
├── 0001-use-postgresql-for-primary-store.md
├── 0002-use-kafka-for-event-streaming.md
└── 0003-adopt-opentelemetry-for-tracing.md
- Number sequentially, never renumber
- Superseded ADRs stay — add "Superseded by ADR-0012" to the status
- Store in-repo alongside code — ADRs are code
Technical Spec Template
Write a spec when the feature is large enough to need design alignment before implementation (> 1 sprint, or involves multiple services).
# Technical Spec: [Feature Name]
**Status:** Draft | In Review | Accepted | Implemented
**Author:** [name]
**Last updated:** YYYY-MM-DD
**Related:** [Jira/Linear ticket], [ADR-XXXX]
## Problem
[1–3 paragraphs: what problem are we solving? Why now? What happens if we don't?]
## Proposed Solution
[Describe the solution at a level where another engineer can implement it.
Include: API contracts, data model changes, component interactions, migration plan.]
### API Changes
[List new or modified endpoints with request/response shapes]
### Data Model
[Schema changes, new tables, index additions]
### Component Diagram
[ASCII or Mermaid diagram showing how components interact]
## Alternatives Considered
| Option | Pros | Cons | Reason not chosen |
|--------|------|------|------------------|
| ... | ... | ... | ... |
## Implementation Plan
1. [ ] Phase 1: ...
2. [ ] Phase 2: ...
3. [ ] Phase 3: ...
## Risks and Mitigations
| Risk | Likelihood | Impact | Mitigation |
|------|-----------|--------|-----------|
| ... | ... | ... | ... |
## Open Questions
| Question | Owner | Due |
|----------|-------|-----|
| ... | ... | ... |
## Stakeholder Sign-off
- [ ] Engineering lead: @name
- [ ] Product: @name
- [ ] Security (if auth/data): @name
Documentation as Code
Keep docs alongside code in the same repository. Auto-deploy to GitHub Pages on merge.
Tool Comparison
| Tool | Language | Best for | Config |
|---|
| MkDocs + Material | Python | Technical docs, clean theme | mkdocs.yml |
| Docusaurus | Node/React | Developer portals, versioned docs | docusaurus.config.js |
| mdBook | Rust | Books, guides (no JS required) | book.toml |
| VitePress | Vue | Fast, modern Vue-based docs | vitepress.config.ts |
MkDocs Example
site_name: Payment Service Docs
theme:
name: material
features:
- navigation.tabs
- search.suggest
nav:
- Home: index.md
- API Reference: api.md
- Runbooks:
- Overview: runbooks/index.md
- High Error Rate: runbooks/high-error-rate.md
- ADRs: adr/index.md
plugins:
- search
- git-revision-date-localized
GitHub Actions — Auto-deploy Docs
name: Deploy Docs
on:
push:
branches: [main]
paths: ['docs/**', 'mkdocs.yml']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: pip
- run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin
- run: mkdocs gh-deploy --force
See also: api-design, system-design, incident-response
Red Flags
- README with only "git clone && npm install" — a quickstart without prerequisites (runtime version, env vars, required services) fails for every new developer; list every dependency
- OpenAPI spec written after the API is built — spec-first forces design conversations before code is committed; spec-after just documents the implementation's accidents
$ref components duplicated across paths — duplicate schemas diverge silently; extract all reusable types to components/schemas and $ref them everywhere
- Runbooks written during an incident — runbooks drafted under pressure are incomplete and inaccurate; write them during calm periods with a junior engineer as the target reader
- Documentation in a wiki separate from the code — wikis go stale because they're not in the PR; docs that live alongside code get updated with the feature or the PR doesn't merge
- ADRs without the rejected alternatives — a decision without context will be relitigated; always record what was considered and why each option was rejected
- Tech spec signed off by a single engineer — one reviewer misses concerns from other domains; require sign-off from security, ops, and data disciplines for anything touching shared infrastructure
Checklist