Skip to content

Design docs template

Three documents, one rule — separate what changes from what must not change.

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.
  1. 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.
  2. 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.
  3. 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. The tour walks the chain and names what each document buys you: a short map at the start, founding ADRs, an RFC that added electric bikes, and a later RFC still in review. Source: openmove/design-docs-example.

CityCycle is a separate repository on purpose. Use this template copies every file in this repository. A filled example kept here would land in every new project.

Terminal window
gh repo create my-project --template openmove/engineering-design-playbook --private

Or 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.

  1. Section 1 — goals, and the top three quality goals as measurable scenarios
  2. Section 3 and the context diagram — who and what the system talks to
  3. Section 4 — half a page on how the design meets those goals
  4. Section 5 and the container diagram — the deployable pieces
  5. 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

The arc42 and MADR files are the official upstream templates, copied in unchanged. Nothing here is a new format. Sources and licenses are in NOTICES.md.

How each folder works: architecture · ADRs · RFCs