When a software application reaches a certain size, documentation of the individual components and their interactions makes sense. Recording architectural decisions is also important to be able to understand why a particular solution was chosen even months or years later. Future colleagues and your future self will thank you for it.

A lightweight method for documenting architectural decisions is through Architectural Decision Records, ADRs.

Architecture Documentation

Every piece of software also has a software architecture. Whether it is actively designed or “emerges” during development depends on the circumstances and requirements. To be able to comprehend and potentially evaluate decisions made on the way to the current state of the software retrospectively, architecture documentation, or at least documentation of the most important decisions, is advisable. Such decisions are often recorded in a wiki, Confluence, or Word document. The documentation thus occurs outside the actual source code and in an unstructured manner, making maintenance and updates challenging.

With arc42 or Structurizr, frameworks exist to systematically document various aspects of software and its architecture. For projects that do not require such extensive documentation, ADRs offer a lightweight solution.

Architectural Decision Records

The goal of Architectural Decision Records is not to describe or reflect the entire architecture of software but to document decisions that have led to the current architecture.

ADRs record architectural decisions in plain text files and prescribe only the format. Each decision gets its own file and a consecutive number. Markdown is used for simple formatting. The files are part of the source code repository, thus being subject to version control. ADRs can be introduced and discussed through pull requests.

Even though the name sets the context to Architecture, ADRs can be utilized for a variety of technical and non-technical decision documentation.

Format

According to the inventor Michael Nygard, ADRs consist of the following fields:

Title: Brief description of the decision.

Context: Description of the context in which the decision was made, including technological, political, or social conditions. The wording is neutral and describes the factual circumstances.

Decision: Describes the decision made in the previously outlined context. The wording is active and describes what will be done: “We will…”.

Status: The status of the decision. Possible values are proposed, accepted, deprecated, or superseded.

Consequences: Describes the resulting state after the decision. Both positive and negative consequences are listed.

Such an ADR document has a length of one to two pages. It represents communication with future developers or ourselves. Therefore, it is important that the documentation is clear, comprehensible, and not just a bullet-point list. For the file name, Nygard suggests a format: doc/arch/adr-NNN.md. Through the unique identifier, individual ADRs can be referenced, such as when later decisions build upon or replace a previous one.

Whether you follow the format shown here or develop your own variation for your project is secondary. What matters is that the format is consistently adhered to throughout the project. Joel Parker Henderson has compiled a series of ADR templates in a GitHub repository.

Example

The ADR for the decision to use RabbitMQ as a message broker might look like the following:

# ADR-039: RabbitMQ Message Broker

## Context

We need a message broker to exchange asynchronous messages
between the individual components of our application. The
solution should be able to operate in a fault-tolerant manner
and persistently store messages. The solution should be hosted
in our own data center and operated by our service team.
RabbitMQ is already in use in other projects, and the service
team is familiar with its operation.

## Decision

We will be using RabbitMQ as the message broker. RabbitMQ
meets our requirements and is already established within the
company. The responsibility for operation will be assigned
to the service team. We will communicate the expected message
volume to the service team.

## Status

accepted

## Consequences

Due to the decision, knowledge for the use of RabbitMQ needs
to be developed within the software team. The service team
will support the software team in the integration process.
The intended use of asynchronous messages between the components
of the application can be implemented.

With such a document, it is also possible to understand retrospectively why RabbitMQ was chosen instead of, for example, Azure Service Bus.

Tools

As ADRs (Architectural Decision Records) represent a structured form of documentation, a variety of tools have been established for their implementation.

adr-tools

Nat Pryce has developed adr-tools, a command-line tool for working with ADRs. This tool allows for the creation of new ADRs in the format described by Michael Nygard.

$ adr init doc/adrs
doc/adrs/0001-record-architecture-decisions.md
$ cat doc/adrs/0001-record-architecture-decisions.md

# 1. Record architecture decisions

Date: 2023-12-28

## Status

Accepted

## Context

We need to record the architectural decisions made on this project.

## Decision

We will use Architecture Decision Records, as [described by Michael Nygard]
(http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).

## Consequences

See Michael Nygard's article, linked above. For a lightweight ADR toolset,
see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).

New ADRs can be created using the command adr new.

$ adr new Write Blog Post about ADRs
doc/adrs/0002-write-blog-post-about-adrs.md

Additional commands allow for linking ADRs, listing them, and generating table of contents for ADRs.

$ adr generate toc
# Architecture Decision Records

* [1. Record architecture decisions](0001-record-architecture-decisions.md)
* [2. Write Blog Post about ADRs](0002-write-blog-post-about-adrs.md)

adr-viewer

adr-viewer generates an HTML page from ADR files. This allows you to integrate ADRs into your CI/CD pipeline and automatically update the documentation.

$ pip install adr-viewer

$ adr-viewer --adr-path doc/adrs --output doc/adrs.html

The generated page provides an overview of all ADRs and allows navigation between individual documents. Different statuses are highlighted with distinct colors, offering a visual indication.

ADR Viewer