Diagrams#

Text-as-diagram DSLs let you describe a diagram in plain text, version it with the rest of the code, and render it as an image. The big three are DOT (Graphviz), Mermaid, and PlantUML.

Why Text Diagrams#

The case for the format. Text diagrams are diff-able, versionable, regenerable, and inline-friendly; they sit naturally in pull requests and documentation that already lives in source control. The trade-off is layout precision, which still belongs to drag-and-drop tools for polished work.

  • Diff-able, changes show up in pull requests like any other text.

  • Versioned with the code they describe.

  • Updateable, regenerate when the system changes; no drag-and-fix-the-arrows ritual.

  • Inline in docs, GitHub renders Mermaid in Markdown; many doc generators support DOT and PlantUML.

  • Cheap, no extra tools required for the consumer; just a renderer.

The cost is less precise control over layout. For polished marketing diagrams, drag-and-drop tools (Figma, Lucidchart) still win.

DOT (Graphviz)#

The oldest and most general; describes graphs (vertices and edges).

digraph deps {
  rankdir=LR;
  node [shape=box];

  api    -> auth;
  api    -> billing;
  billing -> postgres;
  billing -> stripe [label="webhook"];
  auth   -> redis;
}
$ dot -Tsvg deps.dot -o deps.svg
$ dot -Tpng deps.dot -o deps.png

Layouts.

  • dot , hierarchical (default).

  • neato , spring model.

  • fdp , force-directed.

  • sfdp , scalable force-directed; for large graphs.

  • circo , circular.

  • twopi , radial.

Strengths.

  • Handles large graphs better than the alternatives.

  • Many renderers (online, libraries in every major language).

  • The de facto language for compiler IRs, profilers, build-system visualizations, and call-graph tools.

Weaknesses.

  • Verbose for simple flowcharts.

  • Layout is the engine’s call; manual override is awkward.

Mermaid#

Markdown-friendly; renders inline on GitHub, GitLab, Notion, Obsidian, many doc generators.

```mermaid
flowchart LR
    A[Client] --> B(API Gateway)
    B --> C{Authenticated?}
    C -- yes --> D[Service]
    C -- no  --> E[401]
```

Diagram types.

  • Flowchart, flowchart LR / TD.

  • Sequence, sequenceDiagram.

  • Class, classDiagram.

  • State, stateDiagram-v2.

  • ER (entity-relationship), erDiagram.

  • Gantt, gantt.

  • Pie chart, pie.

  • C4 (high-level architecture), C4Context etc.

  • Timeline, Mindmap, GitGraph in newer versions.

Strengths.

  • Inline in Markdown on GitHub.

  • Easy syntax for sequence and flowcharts.

  • Active development; new diagram types appear regularly.

Weaknesses.

  • Layout quality varies; large diagrams get awkward.

  • Less flexible than DOT for non-tree-shaped graphs.

PlantUML#

Java-based; UML-flavoured; deepest support for traditional UML diagrams.

@startuml
actor User
participant Browser
participant API
database DB

User -> Browser : click "Login"
Browser -> API : POST /login
API -> DB : SELECT user WHERE email=?
DB --> API : user row
API --> Browser : 200 + token
@enduml

Diagram types.

  • Sequence, class, use case, activity, component, deployment, state, object, timing, ER, network, archimate, more.

Strengths.

  • Most thorough UML coverage.

  • Stable; many integrations (IDE plugins, CI renderers).

  • Often available offline as a Java JAR.

Weaknesses.

  • Java JVM startup feels slow.

  • Aesthetic is dated by default; themes help.

Choosing#

  • Inline in Markdown / GitHub, Mermaid.

  • Big graphs / call graphs / dependency graphs, DOT.

  • Traditional UML diagrams, PlantUML.

  • All three in the same docs is fine; each one’s strength is real.

Other Notable DSLs#

A handful of newer or specialty diagram languages worth knowing about. D2 chases Mermaid on aesthetics; Structurizr focuses on C4 architecture; Excalidraw versions sketches as JSON; Vega draws data charts; TikZ owns the academic publishing niche.

  • D2 (d2lang.com), modern, opinionated; aim is “Mermaid but better-looking”.

  • Structurizr DSL, focused on the C4 model for software architecture.

  • Excalidraw, not text per se, but .excalidraw files are JSON and version well; sketchy aesthetic suits RFCs and informal diagrams.

  • AsciiFlow / Monodraw, ASCII / Unicode art for terminal-friendly diagrams in plain .txt / Markdown.

  • Vega / Vega-Lite, JSON DSL for data visualizations (charts), not general diagrams.

  • TikZ, LaTeX-based; the choice for academic-style diagrams.

Renderers and Tools#

The tools that turn diagram source into an image. Graphviz renders DOT, Mermaid CLI renders Mermaid, PlantUML server renders PUML, kroki renders all of them through one API. GitHub and GitLab natively render Mermaid in Markdown, so many diagrams need no extra tooling at all.

Versioning Diagrams#

Decisions about what to commit and what to regenerate. Source files diff cleanly; rendered SVGs preview faster but bloat the repo. Most teams commit source only and rebuild on CI; some commit both. Either is fine; the choice matters most for review ergonomics.

A few practical conventions.

  • Keep the source .dot / .mmd / .puml in the repo.

  • Generate the rendered .svg at build time (CI), not commit it.

  • Or commit both, source for diffs, rendered for quick previews.

  • Reference diagrams from docs by their stable filenames.

When Not to Use Text Diagrams#

The cases where the format works against the goal. Polished customer-facing decks want a designer’s tool; heavy manual layout fights the engine; throwaway sketches may be cheaper as a whiteboard photo. For RFCs, ADRs, runbooks, and the revisitable rest, text DSLs win comfortably.

  • Polished, customer-facing slide decks, a designer’s tool wins.

  • Diagrams with many manual overrides; you’ll fight the engine.

  • Anything where the diagram won’t be revisited; a quick whiteboard photo may be cheaper than a Mermaid block.

For everything else (architecture decision records, runbooks, RFCs, incident postmortems, onboarding docs, README diagrams), text-as-diagram DSLs pay back many times over.