← Back to blog

Diagram-as-Code Showdown: 13 Tools, One Pipeline

diagramskrokimermaidd2plantumlgraphvizexcalidrawtools
Diagram-as-Code Showdown: 13 Tools, One Pipeline

The same concept -- Input to Process to Output -- rendered through 13 different diagram-as-code tools via Kroki, a unified API that converts text descriptions into SVG. One POST request per tool. Every diagram shown uses default settings with minimal configuration.

Diagram-as-code tools let you define diagrams in text files that version cleanly, diff meaningfully, and render at build time. No dragging shapes. No attaching PNGs to pull requests. The diagram is text, the output is SVG, and both live in the repo alongside the documentation they support.

Kroki ties them all together. Instead of installing Mermaid, PlantUML, Graphviz, and D2 separately, you send the diagram source to one endpoint and get an SVG back. For a blog or static site, this collapses the toolchain to a single HTTP call.

How it works

Kroki sits in front of 25+ diagram libraries. Send a POST with the diagram source text, get an SVG back. No client-side JavaScript. No installing renderers. For a blog or static site, diagrams render at build time and ship as static assets.

The test concept is the same across every tool: a three-node flow with colored nodes. Each tool received its own idiomatic version of the idea. The source code shown is what was sent to the Kroki API, with a User-Agent header set to avoid Cloudflare blocking.

Using Kroki

The API is a single POST. You encode the diagram type in the URL path and send the source as the request body:

POST https://kroki.io/mermaid/svg
Content-Type: text/plain

graph LR
    A[Input] --> B[Process]
    B --> C[Output]

Change mermaid to d2, plantuml, graphviz, or any of the 25+ supported types and it renders accordingly. That is the entire API. No API keys, no rate limits on the public instance, no account required.

For blog builds, this becomes a pre-render step: iterate over diagram blocks in your markdown, POST each to Kroki, and inline the returned SVG. The result is a fully static page with zero JavaScript for diagrams.

Flow and Structure

Mermaid

Markdown-native. GitHub renders it inline. Best choice for flowcharts in READMEs and docs.

Input

Process

Output

graph LR
    A[Input] --> B[Process]
    B --> C[Output]
    style A fill:#a5d8ff,stroke:#1e90ff

D2

Modern Go-built tool. Cleanest auto-layout of any diagram-as-code tool. Single consistent syntax, built-in themes.

InputProcessOutput

direction: right
input: Input {
  style: { fill: "#a5d8ff" }
}
process: Process {
  style: { fill: "#d0bfff" }
}
output: Output {
  style: { fill: "#b2f2bb" }
}
input -> process -> output

Graphviz (DOT)

The oldest layout engine. Real graph algorithms scale to 200+ nodes. Pure graph power.

Input Input Process Process Input->Process Output Output Process->Output
digraph {
    rankdir=LR
    node [style=filled]
    Input -> Process -> Output
}

Pikchr

Lightweight PIC-inspired markup. Used in SQLite and Fossil documentation. Deterministic output.

Input Process Output
box "Input" fit fill 0xa5d8ff
arrow
box "Process" fit fill 0xd0bfff
arrow
box "Output" fit fill 0xb2f2bb

BlockDiag

Dead-simple block diagrams. Minimal syntax, clean output. Part of the Diag family.

blockdiag blockdiag { node_width = 128 node_height = 48 Input [color="#a5d8ff"] Process [color="#d0bfff"] Output [color="#b2f2bb"] Input -> Process -> Output } Input Process Output
blockdiag {
    Input -> Process -> Output
}

Svgbob

ASCII art to polished SVG. Draw with pipes and dashes. Gets you there from raw text art.

Input Process Output
.------------------.
|    Input          |
'------------------'
        |
        v
 .------------------.
|    Process        |
'------------------'

UML and Architecture

PlantUML

Enterprise UML standard since 2009. Full spec coverage for sequence, class, component, and activity diagrams.

«input»Input«process»Process«output»Output
@startuml
rectangle "Input" <<input>>
rectangle "Process" <<process>>
rectangle "Output" <<output>>
Input --> Process
Process --> Output
@enduml

Nomnoml

Minimalist UML-style syntax. Tiny readable format for quick class and flow sketches.

Input Process Output

C4 Model

Architecture at four levels: Context, Container, Component, Code. Built-in cloud provider icons.

«person»User«container»API[Go] Handles requests«container»Database[PostgreSQL] Stores dataUsesReads/Writes
@startuml
!include <C4/C4_Container>
Person(user, "User")
Container(api, "API", "Go")
ContainerDb(db, "DB", "PostgreSQL")
Rel(user, api, "Uses")
Rel(api, db, "Reads/Writes")
@enduml

SeqDiag

Clean sequence diagrams from the Diag family. Simpler syntax than PlantUML for basic sequences.

blockdiag seqdiag { edge_length = 160 User [label="Client", color="#a5d8ff"] API [label="API", color="#d0bfff"] DB [label="Database", color="#b2f2bb"] User -> API [label="POST /data"] API -> DB [label="INSERT"] DB -> API [label="OK"] API -> User [label="201 Created"] } Client API Database POST /data INSERT OK 201 Created
seqdiag {
    User -> API [label="POST /data"]
    API -> DB [label="INSERT"]
    DB -> API [label="OK"]
    API -> User [label="201 Created"]
}

Data and Specialized

Vega-Lite

Grammar of graphics. JSON-defined bar charts, scatter plots, and maps. Data-driven.

InputOutputProcessstage020406080100valueInputOutputProcessstage
{
  "mark": "bar",
  "encoding": {
    "x": {"field": "stage", "type": "nominal"},
    "y": {"field": "value", "type": "quantitative"}
  }
}

WaveDrom

Digital timing diagrams from JSON. Clock signals, bus transactions, protocol waveforms.

InputProcessOutput
{ signal: [
  { name: "Input",  wave: "01.0.." },
  { name: "Process", wave: "0.1.0." },
  { name: "Output", wave: "0..10." }
]}

Sketch and Hand-Drawn

Excalidraw

Hand-drawn sketch aesthetic. JSON format with collaborative whiteboard editing at excalidraw.com.

InputProcessOutput
(JSON element format with container bindings -- see excalidraw.com for the full schema)

Quick picks

Use caseToolWhy
GitHub READMEMermaidNative rendering in all Markdown. No build step required.
Best-looking outputD2Modern auto-layout, built-in themes. Cleanest defaults of any tool tested.
Enterprise UMLPlantUMLFull spec coverage. Sequence diagrams are best-in-class.
Large dependency graphsGraphvizReal layout algorithms. Scales to hundreds of nodes.
Hand-drawn aestheticExcalidrawWhiteboard vibes. Collaborative editing at excalidraw.com.
All of the above, one APIKrokiPOST text, get SVG. 25+ formats. Zero client JS.

These are default settings. Every tool can be themed, styled, and configured further. The point: pick a format, pipe it through Kroki at build time, and your blog gets diagrams without shipping JavaScript to readers. The diagram source is version-controlled text that diffs cleanly in git.

Termagotchi
_

Ryan Underdown

Autodidact. Rarely listens to advice.

Follow on X @catamarammed or GitHub @underdown