ADR Tooling
Tooling to generate, lint, and index ADRs so they stay consistent as the set grows past 20.
Why
At 5 ADRs you can manage by hand; at 50 the numbering drifts, statuses go stale, and nobody can find the decision about the queue. Tooling automates the boring parts — numbering, status validation, cross-reference checking, and an index page — so the human effort goes into the reasoning. A repo with adr-tools catches 'Status: Accepted' on an ADR that was actually superseded, which is a lie that misleads every new hire.
When
Once you have ≥10 ADRs or expect rapid growth. Setup takes 1-2 hours. Skip only if the project will never have more than a handful of decisions.
How
1. Install adr-tools (npm i -g adr-tools) or use a repo-local script 2. Add a CI step that runs 'adr lint' on every PR touching docs/adr/ - Checks: required sections present, status is a valid enum, numbering monotonic 3. Generate an index: 'adr list' → docs/adr/README.md (auto-regenerated in CI) - Table of number | title | status | date, sorted by number 4. Add a 'adr graph' command (or a small script) that renders supersede links as a Mermaid diagram 5. Wire the index and graph into your internal docs site so they're one click away
Example
.github/workflows/adr.yml:
on: [pull_request]
jobs:
adr:
- run: npx adr-tools lint docs/adr/
- run: npx adr-tools list --format markdown > docs/adr/README.md
adr graph output (Mermaid):
graph LR
ADR0007[PostgreSQL] -->|superseded by| ADR0012[ClickHouse events]
ADR0009[RabbitMQ] -->|superseded by| ADR0013[Kafka]Common Problems
- ⚠Letting the auto-generated index fall out of date because CI only regenerates on PRs that touch docs/adr/ — run it on every main push to catch manual edits.
Best Practices
- ✓Pin the adr-tools version in package.json so a breaking release doesn't suddenly fail every PR.
- ✓Make 'adr graph' output a real SVG committed to the repo — non-engineers can't read Mermaid source but can read a picture.
- ✓Add a 'last reviewed' date to each ADR and a quarterly CI job that flags ADRs unreviewed for 12 months for a freshness check.