Overview

Chapter 02: Architecture Diagramming-as-Code (Mermaid, PlantUML & D2)

Playbook Track: 05 – Presentation Slides & Architecture Diagrams (Visual Systems, Claude Code & Antigravity Workflows)
Target Audience: Year 1 Computer Science & Software Engineering Students Core Tooling Stack: Mermaid.js, D2 (Terrastruct), PlantUML / Graphviz, Gemini 2.5 Flash (DSL Code Gen), Python 3.11+
Delivery Status: 🔍 Ready for Review (Tier 1 Markdown)


1. The Big Picture & Real-World Analogy

Writing in Markdown vs. LaTeX vs. HTML

When writing technical documents, software engineers use different markup languages depending on where the document will live:

  • Markdown: Lightweight, human-readable, and renders natively in GitHub, Notion, and Slack. Great for quick notes and READMEs.
  • LaTeX: The formal academic and mathematical standard with 30 years of history. Requires a heavy compiler, but produces pixel-perfect textbook typography.
  • HTML/CSS: Highly flexible, responsive, and modern.

The "Big Three" Diagramming-as-Code engines share this exact same dynamic:

  1. Mermaid.js (The Markdown of Diagrams): Renders natively inside GitHub READMEs, Notion, and Discord without installing anything. If you need a diagram visible in a Git pull request, Mermaid is king!
  2. PlantUML (The LaTeX of Diagrams): The 20-year enterprise workhorse. Requires Java and Graphviz, but supports every formal UML diagram type and the entire C4 architecture standard library.
  3. D2 (The Modern Next-Gen DSL): Created by Terrastruct to fix the flaws of Mermaid and PlantUML. Features clean modern syntax, superior layout algorithms (TALA), and beautiful default typography.

By representing your system as an abstract intermediate model, you can write once and transpile to whichever engine your team or slide deck requires!


2. Engineering Jargon Demystifier Table

Industry Term What It Actually Means Freshman Student Analogy
Mermaid.js A lightweight JavaScript library that turns simple text into flowcharts and sequence diagrams natively in GitHub. Typing Markdown # Header instead of opening Word and setting font size to 24pt.
PlantUML An open-source tool that uses Graphviz to generate formal UML diagrams from text descriptions. A rigorous compiler like javac that checks and builds formal software blueprints.
D2 (Declarative Diagramming) A modern diagramming language built specifically for software architecture with advanced layout algorithms. A modern styling system like Tailwind CSS compared to 1990s HTML table styling.
Layout Engine (Dagre / Graphviz / TALA) The underlying math algorithm that calculates where boxes sit on the canvas and routes connecting lines without overlaps. A GPS navigation app that calculates the shortest route between points with zero traffic jams.
Transpiler A program that translates source code from one language to another (e.g. converting a Python dictionary into Mermaid and D2). An automated translator converting an English essay into French and Spanish.
Orthogonal Routing Drawing connecting arrows using only 90-degree right angles (horizontal and vertical lines) instead of diagonal slants. Driving on grid-based city streets (like Manhattan) rather than cutting diagonally through parks.

3. The 5-Minute Micro-Lab: The Multi-Engine Transpiler

Run this zero-dependency Python script to see how an in-memory graph is transpiled into both Mermaid.js and D2 formats in under 20 lines of code:

"""
Micro-Lab: Multi-Engine Diagram Transpiler
PB-05 Chapter 2 Micro-Lab (Zero External Dependencies)
"""

def transpile_graph(nodes: list, edges: list) -> dict:
    # 1. Generate Mermaid Flowchart (direction LR)
    mermaid_lines = ["flowchart LR"]
    for src, dst, label in edges:
        mermaid_lines.append(f"  {src} -->|{label}| {dst}")
    mermaid_output = "\n".join(mermaid_lines)

    # 2. Generate D2 Diagram
    d2_lines = ["direction: right"]
    for src, dst, label in edges:
        d2_lines.append(f'{src} -> {dst}: "{label}"')
    d2_output = "\n".join(d2_lines)

    return {"mermaid": mermaid_output, "d2": d2_output}

if __name__ == "__main__":
    nodes = ["WebClient", "APIGateway", "Database"]
    edges = [
        ("WebClient", "APIGateway", "HTTPS REST"),
        ("APIGateway", "Database", "SQL Query")
    ]

    result = transpile_graph(nodes, edges)

    print("=== Transpiled Mermaid.js Code ===")
    print(result["mermaid"])

    print("\n=== Transpiled D2 Code ===")
    print(result["d2"])

4. Comparative Syntax Mechanics & Layout Algorithms

In enterprise software engineering, architectural diagrams serve distinct audiences with varying requirements:

  • Developers reading GitHub pull requests need lightweight, inline diagrams that render natively in Markdown without external dependencies.
  • Enterprise Architects designing multi-region cloud infrastructures require hierarchical container nesting, cloud provider icons, and strict layout routing.
  • Security & Reliability Engineers auditing distributed failure domains need sequence diagrams with explicit synchronous calls, asynchronous event streams, and circuit breaker fallbacks.

To satisfy these demands without manual redrawing, architects must master the "Big Three" declarative diagramming engines: Mermaid.js, PlantUML, and D2.

+---------------------------------------------------------------------------------------------------+
|                     THE BIG THREE DECLARATIVE DIAGRAMMING ENGINES                                 |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|   1. MERMAID.JS                    2. PLANTUML                     3. D2 (TERRASTRUCT)            |
|   - Native in GitHub/Notion        - Enterprise standard           - State-of-the-art modern DSL  |
|   - Zero install (JS in browser)   - C4-PlantUML standard library  - TALA / ELK / Dagre pluggable |
|   - Dagre layout engine            - Graphviz Dot layout engine    - Native container nesting     |
|   - Ideal for READMEs & PRDs       - Ideal for formal UML & C4     - Ideal for complex cloud arch |
|                                                                                                   |
|   SYNTAX CONTRAST:                                                                                |
|                                                                                                   |
|   Mermaid:                         PlantUML:                       D2:                            |
|     flowchart LR                     @startuml                       direction: right             |
|     A[Client] -->|HTTP| B[(DB)]        [Client] --> [DB] : HTTP      client: "Client" ->          |
|                                      @enduml                           db: "DB" { shape: cylinder |
|                                                                        } : "HTTP"                 |
|                                                                                                   |
+---------------------------------------------------------------------------------------------------+

1.1 Layout Engine Mechanics: Dagre vs. Graphviz vs. TALA

A declarative diagram is only as readable as the algorithmic layout engine that positions its vertices and routes its edges:

  1. Dagre (JavaScript / Mermaid):
    • Uses a simplified adaptation of the Sugiyama hierarchical graph drawing algorithm.
    • Computes node ranks, orders vertices within ranks to minimize edge crossings, and calculates B-spline curves.
    • Limitation: Struggles with bidirectional feedback loops and dense non-hierarchical topologies, frequently resulting in awkward line overlaps.
  2. Graphviz Dot (PlantUML):
    • The battle-tested C-based industry standard for hierarchical layout.
    • Extremely rigorous ranking and edge routing with configurable subgraphs and clustering.
    • Limitation: Requires an underlying C/Java runtime; sensitive to minor node additions (can cause entire diagram layouts to jitter or invert).
  3. TALA & ELK (D2):
    • TALA (Terrastruct Architecture Layout Algorithm): The first layout engine designed specifically for software architecture diagrams rather than mathematical trees.
    • Minimizes line bends, handles nested containers naturally, and preserves semantic flow without reversing arrows.
    • ELK (Eclipse Layout Kernel): Open-source force-directed and layered layout engine supporting complex orthogonal routing.

6. Multi-Engine Transpilation & Layout Pipeline State Machine

flowchart TD
    A["Canonical Architecture Model: G = (V, E, Clusters)"] --> B["Multi-Engine Transpiler"]
    B --> C["Mermaid Target: flowchart TD / LR, subgraphs, cylinder shapes"]
    B --> D["D2 Target: direction down / right, nested objects, shape declarations"]
    B --> E["PlantUML Target: @startuml, components, databases, sequence flows"]
    C --> F["Headless Renderer: mmdc CLI -> Scalable SVG"]
    D --> G["D2 Compiler: d2 CLI (TALA / ELK engine) -> Interactive SVG"]
    E --> H["PlantUML Java CLI -> Vector PDF / EPS"]
    F & G & H --> I["Visual QA & Bounding Box Inspection"]

    style A fill:#f5f5f5,stroke:#9e9e9e,stroke-width:2px;
    style B fill:#e8f5e9,stroke:#4caf50,stroke-width:2px;
    style I fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px;

3. Gate 2: Mandatory Manual vs. Programmatic Contrasts

Migrating from manual diagramming to multi-engine Diagramming-as-Code transforms engineering workflows:

Architectural Dimension Manual Dragging (Draw.io, Lucidchart) Programmatic DaC (Mermaid, D2, PlantUML) Operational Consequence
Multi-Format Export Must redraw the entire diagram if switching between a technical wiki and an executive deck. Single canonical model transpiles to Mermaid for GitHub and D2/PPTX for presentations. Huge time savings; zero redundant redrawing across document formats.
Edge Routing Stability Human manually drags Bezier curve handles around boxes to avoid collisions. Algorithmic routing engines (Dagre, Graphviz, TALA) calculate mathematical edge paths automatically. Eliminates human visual fatigue and inconsistent crooked connector lines.
Asynchronous Distinctions Author forgets to change line style; synchronous REST and async Kafka events look identical. Formal syntax guarantees: --> for synchronous blocking calls; -.-> or ->> for async events. Prevents critical distributed systems misunderstandings and race conditions.
Automated Translation Impossible: manual diagrams cannot be automatically translated or ported. Programmatic transpilation via Python AST engines bridges Mermaid, PlantUML, and D2 seamlessly. Enables autonomous AI agents to refactor documentation across enterprise toolchains.
CI/CD Build Automation Broken links in wikis when images are deleted or renamed. Headless CLI compilation validates diagram syntax during Git pre-commit hooks and GitHub Actions. Zero broken diagram images or syntax errors ever reach production branches.

4. Gate 3: Frontier AI Prompts & Transpilation Schemas

Frontier models like Gemini 2.5 Flash excel at generating and transpiling declarative diagram code when guided by rigorous structural rules.

4.1 Multi-Engine Architecture Generator Prompt (gemini-2.5-flash)

SYSTEM INSTRUCTION: You are a Principal Systems Architect and Diagramming-as-Code Specialist.
TASK: Generate both Mermaid and D2 declarative source code for the provided distributed system architecture.
CONSTRAINTS:
1. Identify all services, datastores, queues, and gateways.
2. For Mermaid:
   - Use 'flowchart LR' for horizontal pipelines; 'flowchart TD' for layered tiers.
   - Use [("Datastore")] for databases; (["Gateway"]) for gateways; [["Queue"]] for message brokers.
   - Use dotted lines (-.->) for asynchronous messages; solid lines (-->) for synchronous calls.
3. For D2:
   - Define nested containers with curly braces {}.
   - Explicitly assign shapes: shape: cylinder, shape: queue, shape: cloud, shape: person.
   - Use ->> for asynchronous messaging; -> for synchronous requests.
4. Output structured, compilable DSL code blocks without conversational filler.

4.2 Structured JSON Schema for Architecture Graphs (MultiEngineArchitectureGraphSchema)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "ArchitectureSystemGraph",
  "type": "object",
  "properties": {
    "system_name": { "type": "string" },
    "direction": { "type": "string", "enum": ["TD", "LR"] },
    "clusters": {
      "type": "object",
      "additionalProperties": { "type": "string" }
    },
    "nodes": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "node_id": { "type": "string" },
          "label": { "type": "string" },
          "node_type": { "type": "string", "enum": ["SERVICE", "DATABASE", "QUEUE", "GATEWAY", "USER", "EXTERNAL"] },
          "technology": { "type": ["string", "null"] },
          "cluster": { "type": ["string", "null"] }
        },
        "required": ["node_id", "label", "node_type"]
      }
    },
    "edges": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "source_id": { "type": "string" },
          "target_id": { "type": "string" },
          "label": { "type": "string" },
          "protocol": { "type": ["string", "null"] },
          "is_async": { "type": "boolean" }
        },
        "required": ["source_id", "target_id", "label", "is_async"]
      }
    }
  },
  "required": ["system_name", "direction", "clusters", "nodes", "edges"]
}

5. Gate 4: Quantitative Visual & Tooling Trade-Off Matrix

The following matrix compares the core technical capabilities, CLI dependencies, and layout mechanics across Mermaid, PlantUML, and D2:

Feature / Capability Mermaid.js PlantUML D2 (Terrastruct)
Compilation Dependencies Node.js (@mermaid-js/mermaid-cli) or browser JS Java JRE + Graphviz binaries Single self-contained Go binary (d2)
CLI Compilation Latency Moderate (1.2s – 2.5s via headless Chromium) Moderate (0.8s – 1.8s via Java/Graphviz) Ultra-Fast (0.05s – 0.2s via Go binary)
Native GitHub Markdown Support Universal (Native code blocks in GitHub/GitLab) [FAIL] Requires external rendering proxy or Action [FAIL] Requires GitHub Action or pre-compiled SVG
Nested Subgraph Ergonomics Moderate (subgraphs cannot easily cross boundaries) Good (packages and components) Superior (Arbitrary nested objects {} with scoped IDs)
Layout Engine Support Dagre (Default), ELK (Experimental) Graphviz Dot, Neato, Fdp, Sfdp TALA (Proprietary), ELK, Dagre
Cloud Icons Ecosystem Community font-awesome icons Comprehensive AWS/Azure/GCP sprite libraries Native icon support (icon: https://...)
Interactive HTML Outputs Clickable links only Clickable SVG links Pan, zoom, animated connections, tooltips

6. Gate 5: The 10 Methodological Threats to Validity & Diagramming Pitfalls

When authoring multi-engine architecture diagrams, engineers must avoid ten technical pitfalls:

1. Unescaped Delimiters in Node Labels

  • Threat: In Mermaid, using parentheses or brackets inside a label (e.g., A[Order Service (v1.0)]) breaks the regex parser and causes rendering failure.
  • Defense: Always wrap label strings in double quotes inside the shape brackets: A["Order Service (v1.0)"].

2. Phantom Dependency Inversion

  • Threat: In Dagre/Graphviz layout, adding an upward arrow can inadvertently flip the vertical ranking of the entire diagram, placing the database at the top and the client at the bottom.
  • Defense: Use non-constraining invisible edges or specify explicit rank constraints; in D2, use direction: down.

3. Duplicate Node IDs Across Subgraphs

  • Threat: Defining node db inside Subgraph A and another node db inside Subgraph B creates an unintended merged node in Mermaid.
  • Defense: Namespace all node IDs prefixed with their container or cluster ID (e.g., cluster_a_db, cluster_b_db).

4. Over-Constrained Graphviz Spline Spaghetti

  • Threat: Connecting every microservice to a shared telemetry daemon creates a visual web of crossing lines that obscures system causality.
  • Defense: Omit cross-cutting infrastructure (logging, metrics, tracing) from the core topology diagram and document it in an ADR footnote or dedicated observability view.

5. Asynchronous vs. Synchronous Confounding

  • Threat: Drawing synchronous HTTP REST calls with the same arrow as asynchronous Kafka events, misleading engineers into assuming blocking consistency.
  • Defense: Strict visual contract: solid arrows --> for synchronous blocking; dotted arrows -.-> for asynchronous events.

6. Java Runtime Dependency Failures in CI/CD

  • Threat: PlantUML build jobs failing on minimal Alpine Linux CI containers due to missing graphviz or openjdk system packages.
  • Defense: Use modern single-binary tools like d2 or containerized renderers with pinned digest hashes.

7. Layout Jitter in Git Diff Reviews

  • Threat: A developer adds a single node to a PlantUML diagram, causing Graphviz to calculate a completely different global layout, making the visual diff unreviewable.
  • Defense: Adopt D2's TALA engine, which guarantees localized incremental routing without scrambling existing node positions.

8. Hardcoded Dimension Inflexibility

  • Threat: Specifying fixed pixel widths on nodes that clip long service names or wrap awkwardly on mobile viewports.
  • Defense: Rely on dynamic text-wrapping engines; set standard maximum label character lengths ($\le 32$ chars).

9. Broken Relative Image Links in Exported SVGs

  • Threat: Embedding external icon URLs (http://...) that fail to render when SVG diagrams are viewed in offline PDF reports.
  • Defense: In-line all icon assets as base64 data URIs during the compilation build step.

10. Missing Semantic Legends

  • Threat: Presenting a diagram with 4 different line colors and 3 dashed line patterns without an explanatory legend.
  • Defense: Automatically generate a standardized architectural legend defining all shapes, line styles, and protocol markers.

11. Gate 6: Mandatory Hands-On Lab (Visual Engineering Challenge)

Objective

You will engineer an automated Multi-Engine Diagram Transpiler & Syntax Validator in Python 3.11+, transforming a canonical distributed system graph into idiomatic, validated Mermaid.js and D2 source code.

Experimental Protocol

  1. Model Formulation: Define an e-commerce microservices architecture containing 7 nodes (Web Client, Kong Gateway, Order Service, Payment Service, Kafka Bus, PostgreSQL DB, and Stripe API) distributed across two Kubernetes clusters.
  2. Mermaid Transpilation: Transpile the system model into flowchart LR Mermaid syntax, formatting clustered subgraphs, semantic shapes ([("...")], (["..."])), and explicit protocol labels.
  3. D2 Transpilation: Transpile the same model into modern D2 syntax, verifying nested container scoping ({}), shape properties (shape: cylinder, shape: queue), and asynchronous connectors (->>).
  4. Parity Validation: Programmatically verify that every node and edge in the canonical model is faithfully preserved across both output languages.

9. Summary & Visual Engineering Milestone Checklist

Before moving to Chapter 03 (C4 Model Visual Ontology & Structurizr Automation):

  • Analyzed layout engine mechanics: Dagre vs. Graphviz vs. TALA.
  • Contrasted manual diagramming with multi-engine Diagramming-as-Code.
  • Calibrated Gemini 2.5 Flash prompts for dual-target Mermaid and D2 code generation.
  • Compiled the Quantitative Trade-Off Matrix across Mermaid, PlantUML, and D2.
  • Analyzed and mitigated the 10 Technical Diagramming Failure Modes.
  • Executed and validated the zero-dependency Python 3.11+ multi-engine transpiler engine.