Documentation as Code: ADRs, API Docs, and Living Documentation
Documentation that lives with code stays current. Documentation in wikis goes stale.
Architecture Decision Records (ADRs)
ADRs document why architectural decisions were made.
# ADR-001: Use PostgreSQL as Primary Database
## Status
Accepted
## Context
We need a database for our new e-commerce platform. Requirements include:
- ACID transactions for order processing
- JSON support for flexible product attributes
- Team familiarity with SQL
- Managed hosting availability
## Decision
Use PostgreSQL 15 as the primary database.
## Consequences
**Positive:**
- Strong ACID guarantees
- Excellent JSON/JSONB support
- Wide team familiarity
- Available managed on AWS RDS, Supabase, Neon
**Negative:**
- Vertical scaling limits (addressed by read replicas)
- Requires schema migrations for changes
## Alternatives Considered
- MongoDB: rejected due to lack of ACID transactions
- MySQL: considered, PostgreSQL chosen for better JSON support
# ADR directory structure
docs/
adr/
001-use-postgresql.md
002-use-event-driven-for-notifications.md
003-adopt-trunk-based-development.md
OpenAPI Specification
# openapi.yaml
openapi: 3.1.0
info:
title: User Management API
version: 1.0.0
paths:
/users:
get:
summary: List users
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
- name: cursor
in: query
schema:
type: string
responses:
'200':
description: List of users
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
Code Documentation with JSDoc/TSDoc
/**
* Calculates the shipping cost for an order.
*
* @param order - The order to calculate shipping for
* @param destination - The delivery destination
* @param options - Optional shipping preferences
* @returns The calculated shipping cost in cents
* @throws {InvalidAddressError} If the destination address is invalid
*
* @example
* ```typescript
* const cost = await calculateShipping(order, {
* country: 'US',
* state: 'CA',
* zip: '94102'
* });
* console.log(`Shipping: ${cost / 100}`);
* ```
*/
export async function calculateShipping(
order: Order,
destination: Address,
options?: ShippingOptions
): Promise<number> {
// implementation
}
Generate Docs from Code
# TypeDoc for TypeScript
npm install -D typedoc
npx typedoc --out docs/api src/index.ts
# OpenAPI from code annotations (NestJS)
npm install -D @nestjs/swagger
# Validate OpenAPI spec
npx @redocly/cli lint openapi.yaml
# Generate client from OpenAPI
npx openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o src/generated/api
Readme Best Practices
# Project Name
One sentence description.
## Quick Start
git clone && npm install && npm dev
## Prerequisites
- Node.js 20+
- Docker (for local database)
## Development
npm run dev # Start dev server on :3000
npm test # Run tests
npm run build # Production build
## Architecture
See docs/adr/ for architectural decisions.
API documentation: https://api.example.com/docs
Documentation as code: version-controlled, reviewed, and deployed alongside the software.