Architecture Decision Record (ADR)
An ADR captures one architecturally significant decision — the context that
forced it, the option chosen, and the consequences you now have to live with.
ADRs are short, immutable once accepted, and live in the repo beside the code
they govern so the "why" travels with the "what".
When to use it
Write an ADR when a decision is architecturally significant: it's costly to
reverse, affects the shape of the system, constrains future work, or future
engineers will ask "why on earth is it like this?". Examples: choosing a
datastore, a sync vs async boundary, an auth model, a public API contract, a
build/deploy topology.
When not to use it:
- Reversible, local implementation details → just write good code/comments.
- Broader decisions that aren't about system architecture (product direction,
team process, vendor choice, hiring) → use the kdd (Key Decision Document)
skill, which records stakeholders and a revisit date.
Choosing a format
Two formats are bundled. Both are legitimate — pick by weight of the decision:
- Nygard (
templates/adr-nygard.md) — minimal: Status, Context, Decision,
Consequences. Default for most decisions; fast to write, easy to read.
- MADR (
templates/adr-madr.md) — richer: adds Decision Drivers, an
explicit Considered Options comparison, and Validation. Use when the decision
is contested, has several serious alternatives, or needs an audit trail.
Canonical structure
Nygard (the core four — present in both formats):
- Title —
ADR-NNNN: short imperative phrase (e.g. "Use PostgreSQL for the
primary store"). Numbered, not dated.
- Status —
Proposed → Accepted → later Deprecated / Superseded by ADR-NNNN. Never edit an accepted ADR's decision; supersede it with a new one.
- Context — the forces at play: the problem, constraints, requirements, and
assumptions. Neutral and factual — no solution yet. A reader should feel the
tension that makes the decision non-obvious.
- Decision — the choice, stated in active voice ("We will…"). Just what was
decided and the core reasoning.
- Consequences — what becomes easier and harder afterwards. State the
negatives honestly; every real decision has them. Include follow-on work and
new constraints.
MADR adds, between Context and Decision:
- Decision Drivers — the criteria that actually matter (perf, cost,
team familiarity, operational burden…).
- Considered Options — each serious option with its pros/cons against the
drivers. At least two; "do nothing" is often a valid one.
- Validation (after Decision) — how you'll confirm the decision was right
(a benchmark, a spike result, a metric to watch).
Quality rubric
A strong ADR:
- Captures the tension — Context makes clear why the decision was hard; a
reader could almost predict the options from it.
- Justifies over alternatives — explains why the chosen option beat the
others, not merely what was picked. (MADR makes this explicit; in Nygard, fold
it into Context/Decision.)
- States honest consequences — names the downsides and the new constraints,
not just the wins.
- Is decision-scoped — one decision per record; no implementation manual, no
unrelated decisions bundled in.
- Is discoverable & immutable — numbered, linked from an index; superseded
records point forward to their replacement rather than being edited.
- Is concise — typically one page. If it's longer, it's probably an RFC (use
the rfc skill) and the ADR should record only the resulting decision.
Common pitfalls
- Writing the ADR after implementation as a rubber stamp — write it when the
decision is being made, while alternatives are live.
- Listing only the chosen option (no alternatives, no drivers) — unfalsifiable.
- Burying the decision in a wall of background — keep Context tight.
- Editing accepted ADRs — supersede instead, preserving history.
- Hiding the negative consequences — that's the most valuable part for the
next engineer.
Naming & storage
- Directory:
docs/adr/
- Filename:
NNNN-kebab-case-title.md, zero-padded sequence (e.g.
0001-use-postgresql-for-primary-store.md).
- Maintain
docs/adr/README.md as an index (number, title, status) when the set
grows.
Templates
Copy one of these and fill it in:
templates/adr-nygard.md — lightweight default.
templates/adr-madr.md — richer, for contested decisions.
Sources
1---2name: adr3description: Write or improve an Architecture Decision Record (ADR). Use when capturing a significant architectural or technical decision, when the user mentions ADRs, decision records, "why did we choose X over Y", or wants to document a technical trade-off. For broader non-architectural decisions (product, process, org), use the kdd skill instead.4---56# Architecture Decision Record (ADR)78An ADR captures **one** architecturally significant decision — the context that9forced it, the option chosen, and the consequences you now have to live with.10ADRs are short, immutable once accepted, and live in the repo beside the code11they govern so the "why" travels with the "what".1213## When to use it1415Write an ADR when a decision is **architecturally significant**: it's costly to16reverse, affects the shape of the system, constrains future work, or future17engineers will ask "why on earth is it like this?". Examples: choosing a18datastore, a sync vs async boundary, an auth model, a public API contract, a19build/deploy topology.2021**When *not* to use it:**22- Reversible, local implementation details → just write good code/comments.23- Broader decisions that aren't about system architecture (product direction,24 team process, vendor choice, hiring) → use the **kdd** (Key Decision Document)25 skill, which records stakeholders and a revisit date.2627## Choosing a format2829Two formats are bundled. Both are legitimate — pick by weight of the decision:3031- **Nygard** (`templates/adr-nygard.md`) — minimal: Status, Context, Decision,32 Consequences. Default for most decisions; fast to write, easy to read.33- **MADR** (`templates/adr-madr.md`) — richer: adds Decision Drivers, an34 explicit Considered Options comparison, and Validation. Use when the decision35 is contested, has several serious alternatives, or needs an audit trail.3637## Canonical structure3839Nygard (the core four — present in both formats):40411. **Title** — `ADR-NNNN: short imperative phrase` (e.g. "Use PostgreSQL for the42 primary store"). Numbered, not dated.432. **Status** — `Proposed` → `Accepted` → later `Deprecated` / `Superseded by44 ADR-NNNN`. Never edit an accepted ADR's decision; supersede it with a new one.453. **Context** — the forces at play: the problem, constraints, requirements, and46 assumptions. Neutral and factual — no solution yet. A reader should feel the47 tension that makes the decision non-obvious.484. **Decision** — the choice, stated in active voice ("We will…"). Just what was49 decided and the core reasoning.505. **Consequences** — what becomes easier *and* harder afterwards. State the51 negatives honestly; every real decision has them. Include follow-on work and52 new constraints.5354MADR adds, between Context and Decision:5556- **Decision Drivers** — the criteria that actually matter (perf, cost,57 team familiarity, operational burden…).58- **Considered Options** — each serious option with its pros/cons against the59 drivers. At least two; "do nothing" is often a valid one.60- **Validation** (after Decision) — how you'll confirm the decision was right61 (a benchmark, a spike result, a metric to watch).6263## Quality rubric6465A strong ADR:6667- **Captures the tension** — Context makes clear why the decision was hard; a68 reader could almost predict the options from it.69- **Justifies over alternatives** — explains why the chosen option beat the70 others, not merely what was picked. (MADR makes this explicit; in Nygard, fold71 it into Context/Decision.)72- **States honest consequences** — names the downsides and the new constraints,73 not just the wins.74- **Is decision-scoped** — one decision per record; no implementation manual, no75 unrelated decisions bundled in.76- **Is discoverable & immutable** — numbered, linked from an index; superseded77 records point forward to their replacement rather than being edited.78- **Is concise** — typically one page. If it's longer, it's probably an RFC (use79 the **rfc** skill) and the ADR should record only the resulting decision.8081## Common pitfalls8283- Writing the ADR *after* implementation as a rubber stamp — write it when the84 decision is being made, while alternatives are live.85- Listing only the chosen option (no alternatives, no drivers) — unfalsifiable.86- Burying the decision in a wall of background — keep Context tight.87- Editing accepted ADRs — supersede instead, preserving history.88- Hiding the negative consequences — that's the most valuable part for the89 next engineer.9091## Naming & storage9293- Directory: `docs/adr/`94- Filename: `NNNN-kebab-case-title.md`, zero-padded sequence (e.g.95 `0001-use-postgresql-for-primary-store.md`).96- Maintain `docs/adr/README.md` as an index (number, title, status) when the set97 grows.9899## Templates100101Copy one of these and fill it in:102103- `templates/adr-nygard.md` — lightweight default.104- `templates/adr-madr.md` — richer, for contested decisions.105106## Sources107108- Michael Nygard, "Documenting Architecture Decisions" — https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions109- ADR organization & examples — https://adr.github.io/110- MADR (Markdown Any Decision Records) — https://adr.github.io/madr/