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.1.tar.gz (21.0 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.1-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sphinx_adr-0.3.1.tar.gz
  • Upload date:
  • Size: 21.0 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.1.tar.gz
Algorithm Hash digest
SHA256 7a526464bf18e1af4e17e115332c4145562ce06dc6f5f15390ce6313e15f9fa2
MD5 769d3441aff45b998a0e2b7b57427fa6
BLAKE2b-256 5d841535ae99eaec62944011348a3a2818fae17c21c50431b91dbecf37e2dc37

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sphinx_adr-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 17.9 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1f6e631154a6f09d63ba14e29c17680eef3d496b0738c512517d03a33dd89028
MD5 bb66af5caf2e724e89924b255e010d8d
BLAKE2b-256 78021a47e1de4c551930c93f23f52f0fa7d22488314d243464a24116a1930677

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