Three documents, one rule: separate what changes from what must not change.
Reading view: openmove.github.io/engineering-design-playbook.
Before you write anything, ask one question: is this still being decided, already decided, or describing what exists?
| You are… | Write | When | Can it change? |
|---|---|---|---|
| Still convincing people | RFC — a proposal | Before building | Yes, while in review. Then it is history. |
| Recording a choice | ADR — one decision | The moment you decide | Never. A new ADR supersedes it. |
| Describing the system today | arc42 — the map | Continuously | Yes, always kept current. |
They form a chain. Skipping the last step is how documentation rots.
---
config:
layout: elk
---
flowchart LR
work["New work"] --> q{"Is the solution<br/>obvious?"}
q -->|yes| ticket["Ticket"]
q -->|no| rfc["RFC<br/>propose and review"]
rfc --> adr["ADR<br/>record each decision"]
adr --> arc["arc42 + C4<br/>update the map"]
ticket --> arc
Without this split, every project hits the same three problems:
- Nobody remembers why. Six months in, the reason for a choice left with the person who made it. ADRs keep the reason next to the code.
- The architecture doc is stale. One big document is too expensive to keep current, so nobody does. arc42 splits it into sections, so you update only the one that changed.
- The same debate happens twice. Discussions buried in chat get repeated. An RFC keeps the proposal, the alternatives, and why they lost in one place.
- Never edit an accepted ADR. It is a record of what was true when you decided, like a commit. If the decision changes, write a new ADR and mark the old one
superseded by ADR-NNNN. - Close the loop. An implemented RFC is not documentation of the system. Update the arc42 section and the C4 diagram it touched, in the same change.
- Skip the RFC when the answer is obvious. If there are no trade-offs, a ticket is enough. An RFC that only says "here is how we will build it" is overhead.
CityCycle — a fictional bike-sharing service, published beside this template. The tour walks the chain and names what each document buys you. Source: openmove/design-docs-example.
The example is a separate repository because Use this template copies every file. Keeping CityCycle in this repository would drop a fictional bike-sharing system into every new project.
gh repo create my-project --template openmove/engineering-design-playbook --privateOr choose Use this template on GitHub.
On day one, fill only this. Leave the other arc42 sections empty until there is something real to write.
- Section 1 — goals, and the top three quality goals as measurable scenarios
- Section 3 and the context diagram — who and what the system talks to
- Section 4 — half a page on how the design meets those goals
- Section 5 and the container diagram — the deployable pieces
- The first ADRs — stack, persistence, boundaries, deploy
docs/
architecture/ arc42 9.0, one file per section, plus C4 diagrams in Mermaid
adr/ MADR 4.0 templates and ADR 0000 (we use MADR)
rfc/ RFC template, full and mini
website/ Starlight site that renders docs/ for GitHub Pages
docs/ is the source. Edit and review the Markdown there. website/ only turns it into the reading view; to preview it locally, run npm install and npm run dev inside website/.
The arc42 and MADR files are the official upstream templates, copied in unchanged. Nothing here is a new format. See NOTICES.md for sources and licenses.
How each folder works: architecture · ADRs · RFCs
- arc42 and its section docs
- MADR
- Documenting Architecture Decisions, Michael Nygard
- The C4 model
- Design docs at Google