Skip to main content

Sphinx extension to document Architecture Decision Records (ADRs)

Project description

sphinx-adr

A Sphinx extension for documenting Architecture Decision Records (ADRs) directly inside your Sphinx documentation.

Inspired by ablog (for the directive-based authoring model) and log4brains (for the timeline UI with status badges).

Features

  • .. adr:: directive -- mark any Sphinx page as an ADR with structured metadata (id, status, date, authors, tags).
  • .. adrlist:: directive -- generate a vertical timeline / decision log with filtering and sorting.
  • Sidebar navigation -- compact timeline sidebar on ADR pages (ablog-style html_sidebars pattern).
  • Status badges -- color-coded pills for Proposed, Accepted, Deprecated, and Superseded.
  • ID badges -- teal monospace badge for each record's identifier, visually distinct from status and tags.
  • Timeline layout -- vertical timeline with status-colored glowing dots, cards, excerpts, and tag pills.
  • Works with any Sphinx theme -- tested with alabaster, pydata-sphinx-theme, and sphinx-book-theme.
  • Dark mode support -- automatically adapts to light/dark mode on pydata-sphinx-theme, sphinx-book-theme, and furo.
  • Incremental & parallel safe -- integrates cleanly with Sphinx's build system.

Quick start

1. Install

pip install sphinx-adr

2. Enable the extension

In your Sphinx conf.py:

extensions = ["sphinx_adr"]

# Path to ADR documents (default: "adr")
adr_path = "adr"

# Show the ADR sidebar only on ADR pages (ablog-style pattern)
html_sidebars = {
    "adr/*": ["adr_nav.html"],
}

3. Write an ADR

Create a file such as adr/0001-use-sphinx.rst:

ADR-0001: Use Sphinx for Documentation
=======================================

.. adr::
   :id: ADR-0001
   :status: Accepted
   :date: 2024-01-15
   :authors: Alice, Bob
   :tags: tooling, documentation

   We will use Sphinx as our primary documentation tool.

Context and Problem Statement
-----------------------------

We need a documentation system that supports multiple output formats,
is well-integrated with Python projects, and allows us to write
documentation alongside the code.

Decision Outcome
----------------

Chosen option: **Sphinx**, because it is the de-facto standard for
Python projects and has a rich extension ecosystem.

4. Create a decision log page

Architecture Decision Log
=========================

.. adrlist::

.. toctree::
   :hidden:

   0001-use-sphinx
   0002-adopt-adr-process

5. Build

sphinx-build -b html docs docs/_build/html

Directive reference

.. adr::

Marks the current page as an ADR. Place it near the top of the document, right after the title.

Option Required Description
:id: yes Unique identifier for the ADR, e.g. ADR-0001
:status: yes One of Proposed, Accepted, Deprecated, Superseded
:date: no Date string, e.g. 2024-01-15
:authors: no Comma-separated author names
:tags: no Comma-separated tags for categorisation
:superseded-by: no Docname of the ADR that supersedes this one (when status is Superseded)

The directive body is used as a short excerpt displayed in the timeline listing.

.. adrlist::

Generates a timeline-based listing of all ADRs in the project.

Option Default Description
:status: (all) Comma-separated statuses to include, e.g. Accepted, Proposed
:tags: (all) Comma-separated tags to filter by
:sort: date-desc Sort order: date-desc, date-asc, or status

Configuration

Config value Default Description
adr_path "adr" Directory containing ADR documents
adr_statuses ["Proposed", "Accepted", "Deprecated", "Superseded"] Allowed status values

Sidebar setup (ablog-style)

The extension provides an adr_nav.html sidebar template. Use Sphinx's html_sidebars to control which pages display it:

# Show ADR sidebar only on pages under adr/
html_sidebars = {
    "adr/*": ["adr_nav.html"],
}

Regular pages keep their normal theme sidebar. This follows the same pattern as ablog.

Interactive controls

Timeline

  • Hover on a timeline card to see an elevated shadow and glowing status dot.
  • Click the title link to navigate to the full ADR document.
  • Filter ADRs by status or tags using .. adrlist:: options.

Sidebar navigation

  • Current page is highlighted with bold text and link color.
  • Hover on any entry to see the title highlighted and dot glow.
  • Each entry shows the ID badge, title, and status pill at a glance.

Theme compatibility

Theme Light mode Dark mode Notes
alabaster yes -- Sphinx default, no dark mode
pydata-sphinx-theme yes yes Toggle via navbar switcher
sphinx-book-theme yes yes Built on pydata, same mechanism
furo yes yes Via prefers-color-scheme

Development

Prerequisites

  • Python 3.13+
  • uv

Setup

git clone https://github.com/bngoy/sphinx-adr.git
cd sphinx-adr

# Install in development mode
uv sync --extra dev

Common commands

# Run tests
uv run pytest tests/ -v

# Lint and format
uv run ruff check .
uv run ruff format .

# Build demo docs
uv run sphinx-build -b html docs docs/_build/html

# Build theme examples (requires examples extra)
uv sync --extra examples
uv run sphinx-build -b html examples/pydata-theme examples/pydata-theme/_build/html
uv run sphinx-build -b html examples/book-theme examples/book-theme/_build/html
uv run sphinx-build -b html examples/alabaster examples/alabaster/_build/html

Project structure

sphinx-adr/
├── VERSION                     # Single source of truth for package version
├── pyproject.toml              # Package metadata, build config, ruff config, uv scripts
├── sphinx_adr/
│   ├── __init__.py             # Extension setup, config values, version
│   ├── directives.py           # AdrDirective, AdrListDirective
│   ├── nodes.py                # Custom docutils nodes (adr_meta, adr_list)
│   ├── collector.py            # Metadata collection & timeline rendering
│   ├── templates/
│   │   └── adr_nav.html        # Sidebar navigation Jinja2 template
│   └── static/
│       └── sphinx_adr.css      # Timeline styling, status/ID badges, dark mode
├── docs/                       # Demo site (dogfoods the extension)
│   ├── conf.py
│   ├── index.rst
│   └── adr/                    # Sample ADRs
├── examples/                   # Theme-specific examples
│   ├── alabaster/
│   ├── pydata-theme/
│   └── book-theme/
├── tests/
│   ├── conftest.py             # make_project fixture
│   └── test_extension.py       # 7 tests
└── .github/workflows/
    ├── ci.yml                  # Lint + test on every push/PR
    ├── auto-tag.yml            # Tag repo from VERSION on PR merge
    └── release.yml             # Build and publish to PyPI on tag

License

Apache 2.0 -- see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sphinx_adr-0.3.0.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sphinx_adr-0.3.0-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file sphinx_adr-0.3.0.tar.gz.

File metadata

  • Download URL: sphinx_adr-0.3.0.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sphinx_adr-0.3.0.tar.gz
Algorithm Hash digest
SHA256 f4532a45f110a33b26a60caeb199a7a4f3234c9d6403acb89be6b043d7ac0dfd
MD5 9116eb3ec37b73e93e706689247d443b
BLAKE2b-256 9ad50e3f673cf6601313d2c141c7516264301b022111958ed633d3522e5a2576

See more details on using hashes here.

File details

Details for the file sphinx_adr-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: sphinx_adr-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sphinx_adr-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e9dbd97abecb75e3c112c08323cd1183c323ef0c218d5195b6c69a70c7e78a0
MD5 be29327971d9149356c83ba03cc5d1cb
BLAKE2b-256 6903eca4a5bb5f1df135bac7daa2591497b5e63e3c06753211607951a12f8403

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page