Last updated June 03, 2026

Originally published on June 02, 2026

Tracking architectural decisions in Django

Technical decisions rarely get written down anywhere useful. They happen in chat threads, in meetings, inside a developer's head — and then they evaporate. The result is predictable: lost context, repeated debates, and avoidable mistakes.

A few months later someone asks why did we pick this library over that one? and the answer is either a shrug or a dig through old PRs. Git history tells you what changed, not why the team decided to change it.

That gap is what Architectural Decision Records are designed to fill.

What is an ADR?

An Architectural Decision Record is a short, structured document that captures a single significant technical decision: its context, the reasoning behind it, and its consequences.

The format was popularized by Michael Nygard and is intentionally minimal. A typical ADR has:

  • Title: a noun phrase describing the decision (Use a relational database)
  • Status: where this decision currently sits in its lifecycle
  • Context: the forces at play: constraints, options, what problem prompted this
  • Decision: what was actually decided
  • Consequences: what follows from this decision, good and bad

The statuses are what make ADRs a living record rather than a static document:

  • proposed: under discussion, not yet agreed
  • accepted: agreed and in effect
  • deprecated: no longer relevant, but not replaced
  • superseded: replaced by a newer ADR
  • rejected: considered and not adopted

An ADR doesn't change once accepted. If the decision changes, you write a new ADR that supersedes the old one. The history is preserved.

Enter django-adr

django-adr is a Django reusable package that brings ADR management into your Django project with minimal setup.

The core insight is: your ADRs should live close to your project. Not in a wiki page that drifts, not in a shared doc that nobody keeps up to date, but inside the system the team is already working in every day.

A few things make it practical:

  • Django Admin interface
  • HTML list and detail views
  • Read-only REST API
  • Management commands (create_adr, export_adrs)
  • Markdown support in all text fields

Docs-as-code: exporting to Markdown

The export_adrs command writes each ADR to a Markdown file inside the repository. Commit those files, and architectural decisions travel with the code they describe — visible in code review, in the file browser, and in any docs site generated from the repo.

The database remains the source of truth; the exported files are a snapshot for readers who prefer to stay in their editor.

Why this matters beyond engineering

Developers naturally care about ADRs because they're the ones living with the consequences of architectural decisions day to day. But they matter at least as much for anyone in a tech product role.

The /adrs/ view is deliberately simple and readable. It's not a developer-only artifact. It's a shared record for everyone working on the product.

When writing a new spec or sizing a feature, ADRs answer the questions that need answering before requirements can be written — without scheduling a meeting.

When a stakeholder asks why does the app work this way, pointing to a written record is better than reconstructing a conversation from memory.

When a new developer joins the team, ADRs are the fastest way to hand them the institutional knowledge that otherwise lives in the heads of the two people who've been on the project longest.

The hardest part of ADRs has never been the tooling. It's building the habit of writing them. Having the tool inside your existing stack, with zero context switching, is one less reason not to.

Copyright © 2026 Niccolò Mineo
Some rights reserved: CC BY-NC 4.0