Topic: log4brains adr

Log4Brains ADR — Generate an Architecture Decision Record Website from Your Codebase

Your ADRs live in doc/decisions/ and almost nobody reads them there. Log4Brains solves the discoverability problem: it reads those same Markdown files and generates a searchable static website — a timeline of decisions, status badges, supersession links, and full-text search — that non-engineers can browse without cloning the repository. This page covers installation, the log4brains.yml configuration, workspace mode for monorepos, GitHub Pages deployment, how Log4Brains compares to adr-tools, and the three limitations teams hit most often.

TL;DR

Log4Brains is the publishing layer for your ADR practice. It reads Nygard-format (or YAML-frontmatter) ADR Markdown files and generates a Next.js-based static site showing every decision, its status, its supersession chain, and full-text search. Install: npm install --global log4brains. Initialize: log4brains init. Preview: log4brains preview. Build: log4brains build (output: _log4brains/). Deploy the output directory to GitHub Pages, Netlify, or any static host. It complements adr-tools rather than replacing it — both create ADR files; Log4Brains adds the searchable web view on top.

What Log4Brains does — and what it doesn't

Log4Brains (github.com/thomvaill/log4brains, author Thomas Vaillant) is an open-source Node.js CLI with two functional modes:

What Log4Brains does NOT do:

Install and first run

Log4Brains requires Node.js ≥ 14. Install globally:

npm install --global log4brains

Then initialize Log4Brains in your repository root. The interactive setup asks for your project name and the directory where your ADRs live:

cd my-project
log4brains init

The init command creates a log4brains.yml file at the project root and scaffolds an initial ADR template in your decisions directory. If you already have ADR files in doc/decisions/, they'll be detected automatically — no migration needed.

Preview the generated site locally (runs a Next.js dev server at localhost:4004 by default):

log4brains preview

Create a new ADR (creates a numbered Markdown file using your template):

log4brains adr new "Use PostgreSQL for user data"
# Creates: doc/decisions/0003-use-postgresql-for-user-data.md

Build the static site (output goes to _log4brains/):

log4brains build

The log4brains.yml configuration file

The config file lives at your project root. A minimal single-package config:

project:
  name: my-project
  decisions:
    location: doc/decisions
    titleFormat: "[{deciders}] {title}"   # optional: controls the site's list view title

Key fields:

Field What it controls Default
project.name The site title shown in the generated UI Derived from package.json
project.decisions.location Path to the directory containing ADR Markdown files (relative to repo root) Required
project.decisions.titleFormat Template for ADR titles in the list view — can reference frontmatter fields {title}
packages Array of sub-packages for workspace/monorepo mode (see below) Omit for single-package repos

Log4Brains parses Status from the ADR Markdown body (## Status\nAccepted in Nygard format) and from YAML frontmatter (status: Accepted). It recognizes the standard values: Proposed, Accepted, Deprecated, and Superseded. Supersession relationships are parsed from body text — it looks for "Supersedes [ADR-NNNN]" and "Superseded by [ADR-NNNN]" patterns in the Status or Consequences sections.

Workspace mode for monorepos

If your repository contains multiple packages (a monorepo), each with their own ADR directory, Log4Brains can aggregate them into a single site with per-package filtering. Add a packages array to log4brains.yml:

project:
  name: my-platform
  decisions:
    location: docs/decisions           # shared / cross-cutting decisions

packages:
  - name: api
    decisions:
      location: packages/api/docs/decisions
  - name: frontend
    decisions:
      location: packages/frontend/docs/decisions
  - name: infra
    decisions:
      location: packages/infra/docs/decisions

The generated site shows all ADRs across all packages in a unified timeline, with a per-package filter in the sidebar. The ADR number namespace is scoped per package — package api can have ADR-0001 without colliding with the shared decisions' ADR-0001.

When to use workspace mode vs a flat directory:

Deploy to GitHub Pages

The most common deployment target for Log4Brains sites is GitHub Pages. The workflow deploys on every push to main that touches the ADR directory:

name: Deploy Log4Brains ADR site

on:
  push:
    branches: [main]
    paths:
      - 'doc/decisions/**'
      - 'log4brains.yml'

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0          # Log4Brains uses git history for dates

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Build Log4Brains site
        run: npx log4brains build

      - name: Add .nojekyll
        run: touch _log4brains/.nojekyll

      - uses: actions/upload-pages-artifact@v3
        with:
          path: _log4brains/

      - id: deployment
        uses: actions/deploy-pages@v4

Two non-obvious requirements in this workflow:

For Netlify or Vercel, the setup is simpler: configure the build command as npx log4brains build and the publish directory as _log4brains. No .nojekyll file needed on those platforms.

Log4Brains vs adr-tools: a comparison

Log4Brains adr-tools (npryce)
Primary purpose Generate a searchable static site from existing ADR files Create numbered ADR files and manage supersession links
Create new ADR log4brains adr new "Title" (Node.js) adr new "Title" (shell script)
Web UI output Full static site (Next.js), searchable, filterable by status None — text files only
Supersession tracking Reads from body text; renders as a graph in the site Inserts links via adr link / adr generate
Runtime requirement Node.js ≥ 14 POSIX shell (works on any Unix-like system)
CI integration GitHub Actions workflow for Pages deploy Combine with ADR GitHub Action for quality gates
Monorepo support Workspace mode (multiple packages in one site) Not built-in; typically one adr per package
Format support Nygard + YAML frontmatter variants Nygard only (shell template)
Install npm install --global log4brains brew install adr-tools or from source
Right when Your team includes non-engineers or your ADR count exceeds ~30 (git navigation gets slow) Your team is all engineers, comfortable with git, and wants minimal tooling overhead

The two tools aren't mutually exclusive. Some teams use adr-tools for local ADR creation (because the shell scripts are fast and have no runtime dependency) and Log4Brains for the published view (because the web UI is what stakeholders actually use). The files are compatible — adr-tools produces Nygard-format files that Log4Brains reads without modification.

Three limitations teams hit most often

1. Build time grows with ADR count and git history size

Log4Brains' build command runs git log on every ADR file to extract authorship dates. For repositories with long histories (thousands of commits) and large ADR directories (100+ files), this can make the build slow — sometimes 2-5 minutes. The mitigation is to scope the GitHub Actions workflow with a paths filter (so the deploy only runs when ADRs actually change) and to use a self-hosted runner with the repo already warm-cloned so the full fetch-depth: 0 checkout doesn't repeat the full clone on every run.

2. Custom templates require forking or upstream contribution

Log4Brains uses a built-in ADR template for log4brains adr new. Teams that want a custom template (to add TOGAF fields, require specific frontmatter, or use a lightweight three-field format) can't configure the template in log4brains.yml — they need to either patch the installed package or submit a PR to upstream. The workaround most teams use: skip log4brains adr new for file creation (use adr-tools or a custom cp template.md script instead) and use Log4Brains only for the build step. The build step reads any valid ADR file regardless of which tool created it.

3. The generated site requires JavaScript

The Log4Brains static site is a Next.js application. It uses client-side JavaScript for search, filtering, and navigation. If your stakeholders need to browse ADRs on a network with a strict content security policy that blocks JavaScript, or if you need to serve the site in a fully offline environment (such as a secure enclave), the Log4Brains output won't work. In those environments, generate Markdown documentation with adr generate toc (adr-tools) and serve the Markdown files via a simple static server or a Docusaurus / Hugo deployment instead.

Pairing Log4Brains with CI quality gates

Log4Brains handles the publishing layer. For the creation and quality-gate layer, pair it with:

The full lifecycle: decide a decision warrants an ADR → create the file (adr-tools or log4brains adr new) → review against the checklist → CI validates structure and numbering → PR merges → Log4Brains GitHub Action rebuilds the site → stakeholders find the decision via search.

How WhyChose fits in

Log4Brains solves the discoverability problem for ADRs that already exist in your repository. It doesn't solve the upstream problem: most architecture decisions never become ADRs at all. They're made in ChatGPT or Claude conversations, recorded nowhere, and discovered only retrospectively when a new engineer asks why the stack looks the way it does.

The WhyChose extractor is the feed for Log4Brains' input directory. It reads your ChatGPT or Claude export, surfaces every decision-shaped conversation with the original reasoning intact, and outputs structured records in Nygard-format Markdown — ready to drop into doc/decisions/. From there, the GitHub Action assigns a number, Log4Brains adds the decision to the site, and the decision becomes searchable by any stakeholder. The full pipeline: AI chat → WhyChose extractor → doc/decisions/ → Log4Brains site → stakeholders.

Get early access

Related questions

What is Log4Brains and what does it do?

Log4Brains is an open-source Node.js CLI (github.com/thomvaill/log4brains) that reads your ADR Markdown files and generates a searchable static website — a timeline of decisions, status badges, supersession links, and full-text search. It adds the publishing layer to your ADR practice: instead of navigating doc/decisions/ in a git repo, team members and stakeholders browse a web UI. It also provides log4brains adr new for creating new ADR files, similar to adr-tools. The primary value is the generated site, not the file creation.

How is Log4Brains different from adr-tools?

adr-tools (npryce/adr-tools) is a set of shell scripts that create and link ADR files — write-only tooling, no web UI. Log4Brains is a Node.js CLI with two modes: file creation (like adr-tools) and site generation (unlike adr-tools). The meaningful difference is the output: adr-tools produces numbered Markdown files; Log4Brains produces a searchable website. Many teams use both: adr-tools or log4brains adr new for creating files, and log4brains build + GitHub Pages for the published view. The file formats are compatible — adr-tools' Nygard-format output is read by Log4Brains without modification.

Does Log4Brains work with existing ADR files in Nygard format?

Yes, without migration. Log4Brains reads Nygard-format files and displays all five sections (Title, Status, Context, Decision, Consequences). It parses Status from the body (## Status\nAccepted) rather than requiring YAML frontmatter. The main requirement is the NNNN-slug.md filename convention — files that don't follow this pattern may not sort or display correctly. adr-tools and log4brains adr new both produce files in this format by default. If your existing ADRs have inconsistent naming, the numbering scheme guide covers how to normalize without rewriting your git history.

How do I deploy Log4Brains to GitHub Pages?

Run log4brains build to generate _log4brains/, add a .nojekyll file inside it (to prevent GitHub Pages' Jekyll from stripping underscore-prefixed paths), then deploy the directory via the GitHub Pages Actions (actions/upload-pages-artifact + actions/deploy-pages). Use fetch-depth: 0 in the checkout action — Log4Brains reads git history for ADR creation dates, and a shallow clone produces wrong or blank dates. Scope the workflow with a paths filter on your ADR directory so the deploy only runs when decisions actually change.

Further reading