Docs & Code Guide

Docs as code for diagrams: the honest limits of text-defined layouts and the hybrid that keeps both strengths

Docs-as-code is the right call for prose, and this page will not pretend otherwise. The question is narrower: whether diagrams belong in the same pipeline, as text compiled to pictures. The honest answer is sometimes. Text-defined diagrams are excellent below a size threshold and degrade sharply above it, and the failure modes are specific enough to name.

7 min readFor docs-as-code teams whose diagrams stopped fitting

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

164/20003 credits left
Try:

No account needed · Editable canvas, not a picture

Where docs-as-code wins outright

For prose, the model is close to unbeatable: ADRs, runbooks, and design docs in the repo get reviewable diffs, atomic commits with the code they describe, blame for every sentence, and CI enforcement of links and style. An ADR recording why the queue exists belongs in git, full stop, and the docs checks a CI pipeline can run all assume this arrangement.

Small diagrams inside that prose inherit the wins. A Mermaid sequence diagram of one flow, living in the same file as the ADR that motivates it, versioned in the same commit as the code change, is docs-as-code at its best, and GitHub renders it natively from a fenced code block, no toolchain required. The comparison with the broader living-documentation approach is drawn in living documentation vs docs as code.

Limit 1: generated layout stops scaling around 20 nodes

Text-defined diagrams delegate layout to the renderer, and that delegation is the source of both the convenience and the ceiling. Mermaid is excellent for small flows, and past roughly 20 nodes the generated layout starts working against the reader: edges cross unpredictably, related nodes drift apart, and there is no way to pin a box where comprehension wants it. The features architecture diagrams lean on hardest degrade first, nested zones for network boundaries strain subgraph layout, and column-level detail on data stores is beyond what the generated layout will hold legibly.

This is not a bug to wait out, it is the design trade. A language that frees you from placing boxes cannot also promise the placement a fifty-node platform overview needs.

Limit 2: the diff is not the diagram

Docs-as-code justifies itself through review, and diagram formats undercut review from both directions. Hand-positioned formats like draw.io XML produce diffs of shifted coordinates that no reviewer can read, and concurrent edits conflict unmergeably, the full story is in diagram versioning. Generated formats like Mermaid produce clean text diffs, but the diff shows the source, not the render: adding one node can reshuffle the entire layout, so a reviewer who approved three changed lines has not seen what readers will see. Without a preview step in the PR, diagram review approves the spelling of the change, not the picture.

The hybrid: prose in git, the big diagram embedded and regenerable

The split that keeps both strengths: prose and small flow diagrams stay in git as text, and the large architecture diagram lives in an editor built for layout, embedded into the markdown as an image URL. The page in git then always shows the current diagram, because the embed follows its source, Datadef serves it with a five minute cache lifetime, so an edit appears in the rendered page within minutes, with no image files committed and no export step.

The diagram stays connected to the code through a different channel than the commit: an agent connected to Datadef's MCP server can redraw it from what the repo contains, invoked after merges or from CI. Two honest limits: the embed URL exists only for projects shared public, and Datadef does not watch the repository, regeneration is one agent call away rather than automatic. The README mechanics, GitHub strips iframes so the image URL form is the one that works there, are covered in embedding diagrams in Markdown.

# ADR-042: Split the billing worker out of the monolith

Status: accepted
Date: 2026-08-12

## Current architecture

![Billing architecture](https://datadef.io/api/embed/billing-platform-a1b2c3d4)

The image above is a live embed: when the diagram changes, this
page follows within minutes, with no new commit to this file.

## The charge flow, small enough to stay in Mermaid

```mermaid
sequenceDiagram
  Checkout->>Billing: charge.requested
  Billing->>PSP: create payment
  PSP-->>Billing: webhook payment.succeeded
  Billing->>Ledger: post entries
```

A rule of thumb that survives contact

Count nodes and ask who edits. Under 20 nodes, one flow, edited by whoever edits the surrounding prose: write it in Mermaid, in the same file, and enjoy the atomic commits. Over that, or needing zones, pinned layout, or datastore column detail, or edited by people who do not live in the repo: draw it in a layout-capable editor and embed it by URL. The wrong choice in either direction has a signature, unreadable renders in the first case, stale pasted exports in the second.

The boundary in one sentence

Text-defined diagrams for flows small enough to need no layout decisions; embedded, regenerable diagrams for anything with zones, scale, or an audience beyond the repo.

FAQ

What are the limitations of docs-as-code for diagrams?

Three main ones. Generated layouts stop being legible at scale: Mermaid is excellent for small flows and struggles past roughly 20 nodes, with nested zones and column-level detail degrading first. Reviews are unreliable: hand-positioned XML formats diff as coordinate noise, while generated formats diff cleanly but the rendered layout can change in ways the text diff does not show. And concurrent edits to layout-bearing files conflict unmergeably.

What are Mermaid's limits for large architecture diagrams?

Layout control. Mermaid computes the layout, so past roughly 20 nodes edges cross unpredictably and related components drift apart, with no way to pin positions. Nested subgraphs, the natural encoding for network zones, strain the layout further, and column-level detail on data stores is beyond it. Below that scale, and especially for sequence and flow diagrams inside a doc, it is genuinely excellent, and GitHub renders it natively.

Are diagrams as code better than visual diagram tools?

For small flows living next to prose in the same commit, yes: versioning, review, and atomicity are real advantages. For large system diagrams needing deliberate layout, zones, and non-repo audiences, visual tools win, and the gap does not close with effort. Most teams do best with both: Mermaid for flows inside docs, a layout-capable tool for the platform overview, embedded by URL so the git-hosted page stays current.

How do teams review diagram changes in pull requests?

For Mermaid, with a render step: either the platform previews it, GitHub renders Mermaid in markdown files natively, or CI posts a rendered image to the PR, because the text diff alone does not show layout shifts. For draw.io XML and similar formats, meaningful diff review is not realistic; teams review a rendered before-and-after or move the diagram out of the merge path entirely by embedding a single canonical version.

What is the hybrid approach for docs-as-code and diagrams?

Prose, ADRs, and small Mermaid flows stay in git as text. The large architecture diagram lives in a layout-capable editor and is embedded into the markdown by image URL, so the page always shows the current version without committed image files. The diagram is kept current by an agent that redraws it from the repo on request, rather than by hand-editing text at a scale text cannot hold.