mkdocs-decision-records
August 26, 2026 · View on GitHub
Manage decision records with mkdocs in a customizable and minimal fashion.
Features
- Customizable status colors and lifecycle
- Enforces information to be present for ADRs
- Allows description being kept as markdown
Demo
You can find a Demo on GitHub Pages
Installation
- Install
mkdocs-decision-recordsfrom the PyPi registry using your favorite package manager - Configure your
mkdocs.ymlplugins: - decision-records: # Folder where your decision records are located, defaults to adr decisions_folder: adr # Optional prefix to prepend to ticket numbers ticket_url_prefix: https://ticket.example.com/ # Configure amount of required deciders required_deciders_count: 1 # Configure the length of decision IDs (default: 3) decision_id_length: 3 # Enable validation that IDs match the configured length (default: false) # When enabled, IDs that don't match the configured length will be rejected validate_id_length: false # Configure available stages and the badge colors lifecycle_stages: {status}: {color} - Create your ADRs ensuring to add the frontmatter meta data:
--- id: 000 status: proposed | rejected | accepted | deprecated | … | superseded [superseded_by: <id it has been replaced with>] date: YYYY-MM-DD deciders: - decider 1 - decider 2 # Optional ticket ticket: FOO-1 --- ## Context and Problem Statement [Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.] ## Decision Drivers <!-- optional --> * [driver 1, e.g., a force, facing concern, …] * [driver 2, e.g., a force, facing concern, …] * … <!-- numbers of drivers can vary --> ## Considered Options * [option 1] * [option 2] * [option 3] ## Decision Outcome Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)]. ## Pros and Cons of the Options <!-- optional --> ### [option 1] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ### [option 2] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ### [option 3] [example | description | pointer to more information | …] <!-- optional --> * Good, because [argument a] * Good, because [argument b] * Bad, because [argument c] * … <!-- numbers of pros and cons can vary --> ## Links <!-- optional --> * [Link type] [Link to ADR] <!-- example: Refined by [ADR-0005](0005-example.md) --> * … <!-- numbers of links can vary -->
Superseding ADRs
This plugin is opinionated about using superseded status.
When setting the status to superseded, make to sure also set superseded_by to the ADR id it has been replaced with.
---
# adr details
status: superseded
superseded_by: 123
---
<!-- Deprecated ADR -->
Generated decision index
On every build, the plugin writes a decision_index.json to the root of the built site (e.g. site/decision_index.json).
It contains one entry per decision record (templates excluded), and can be used to build custom search or listing
features on top of the generated site.
Each entry has the shape:
{
"id": "000",
"date": "2024-01-01",
"title": "Example decision",
"status": "accepted",
"url": "adr/000-example-decision/",
"deciders": ["Jane Doe"],
"ticket": "FOO-123",
"toc": "...",
"sections": [
{ "title": "Context and Problem Statement", "text": "..." }
],
"superseded_by": "001"
}
urlis the rendered page's URL, relative to the site root (join it with the site's base URL to get a link to the decision record)decidersandticketmirror the record's frontmatter;decidersis[]andticketisnullwhen not settocis the page's table of contents, as produced by MkDocssectionslists the page's headings with their rendered text contentsuperseded_byis only present whenstatusissuperseded
Motivation
I love ADRs and documenting decisions in general. This plugin makes it a bit easier, enforcing basic meta information while keeping the format open enough so you can do your thing.
Contributing
I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the configuration
- Submitting a fix
- Proposing new features
- Becoming a maintainer
To get started please read the Contribution Guidelines.
Development
Requirements
- Python 3.12+
- Poetry
Build
poetry install
Alternatives
- mkdocs-material
- Needs to use the theme
- ADR graph
- mkdocs-macros-adr-summary
- works entirely with macros
- no metadata table at the top