CLI reference
diago is one binary with four verbs. Every verb reads a spec and writes its result to stdout; warnings and errors go to stderr. Getting started shows them in use.
| Verb | Does |
|---|---|
diago render [flags] [SPEC] |
Draws one spec in the chosen format. |
diago diff [flags] PATH |
Draws the latest change of a file kept in git. |
diago diff [flags] OLD NEW |
Draws one picture of what changed between two specs. |
diago check [-strict] [-json] [SPEC] |
Prints advisories without laying anything out. |
diago import [SPEC] |
Translates a Mermaid source into a diago JSON spec. |
diago help [verb] |
Prints the usage, or a verb’s usage and flags. |
diago --version |
Prints the installed version: a release tag such as v0.5.0, the commit it was built from, or (devel) when the binary carries no version. |
Every call names its verb. diago spec.json and diago -format text spec.json are errors that
print the usage (exit 2), with a did you mean: diago render … hint when the word looks like a
spec. Help you ask for goes to stdout with exit 0: diago -h, --help or help print the
usage, and diago help <verb> or -h/--help on a verb print that verb’s usage and flags. A bad
flag prints its error and the verb’s usage on stderr, exit 2. diago --version (or
diago version) prints diago <version>.
A SPEC is a path, - or nothing (stdin, for render, check and import; diff reads files
only), or REV:PATH: the file as it was at a git revision, such as HEAD~1:arch.json,
v1.2:arch.json or a commit hash. PATH is relative to the current directory, and the repository
is the one that contains it; a name that exists on disk is always read as a file. Reading a
revision needs git on PATH, and a symbolic link at that revision is refused: git keeps the
link’s text, not the spec it points to. With one PATH, diff draws that file’s latest change: the newest
version committed along first parents from HEAD, following renames, whose content differs from
the file on disk, against the file on disk.
A Mermaid file renders as it is: diago render diagram.mmd. Mermaid sources are accepted wherever
a spec is. A path ending in .mmd or .mermaid, or a body
whose first meaningful line is flowchart, graph, sequenceDiagram or classDiagram, is
translated before parsing. This holds for render, check, both arguments of diff and the
-previous argument. Constructs diago cannot carry are translated to their nearest form and
reported on stderr; statements with no meaning in diago fail with a line number. The mapping is
under diago import.
Flags may come before, between or after the paths, on every verb: diago render spec.json -format text and diago render -format text spec.json are the same call. A -- ends the flags.
diago render
Section titled “diago render”| Flag | Default | Notes |
|---|---|---|
-format |
svg |
svg, png, text (alias txt), drawio, excalidraw (the last two in beta). An unknown value is an error, never a silent fallback. |
-theme |
the spec’s theme, else default |
default, dark, midnight, sketch, or a theme file in DIAGO_THEME_DIR. Overrides the spec’s field. Text art takes no theme, but the name must still load. An unknown name is an error. |
-scale |
2.0 |
PNG only. Ignored when -width is set. |
-width |
none | PNG width in pixels. Overrides -scale. |
-previous |
none | Anchors the layout on an earlier render, so the nodes that survive an edit stay close to where they were. Flow and class only. See Anchoring on a previous render. |
-debug |
off | Writes one JSON line per layout decision to stderr. See Debug logging. |
diago diff
Section titled “diago diff”| Flag | Default | Notes |
|---|---|---|
-format |
svg |
svg, png, text (alias txt). drawio and excalidraw are not available for a diff. |
-theme |
the new spec’s theme, else default |
The old spec’s theme field is not read. |
-scale |
2.0 |
PNG only. Ignored when -width is set. |
-width |
none | PNG width in pixels. Overrides -scale. |
-debug |
off | JSON Lines layout decisions on stderr. |
diff has no -previous: for a flow or class diagram it always anchors the union of the two specs
on the old layout. A sequence diff is not anchored.
diago check
Section titled “diago check”| Flag | Default | Notes |
|---|---|---|
-strict |
off | Exit 1 when any finding remains after the spec’s ignore list. |
-json |
off | Print {"warnings": [...]} instead of one line per finding. |
check validates the spec as render does, the theme it names included, and exits 1 on an
error. It never lays a diagram out, so three findings appear only on render and diff:
text-label-dropped and flat-edge-ranked, which come from the layout, and edge-without-id,
which only render -previous and diff report, since only they match elements by id. The
advisories page lists every rule.
diago import
Section titled “diago import”import takes no flags, only an optional path. It writes the JSON spec to stdout and report lines to
stderr.
Formats
Section titled “Formats”| Format | render |
diff |
Types |
|---|---|---|---|
svg |
yes (default) | yes (default) | flow, sequence, class |
png |
yes | yes | flow, sequence, class |
text or txt |
yes | yes | flow, sequence, class |
drawio beta |
yes | no | flow only |
excalidraw beta |
yes | no | flow only |
PNG is the SVG rasterized by resvg, which must be
installed (see Environment variables). Without it -format png fails
with an install hint and the other formats still work. A PNG is 2.0 times the SVG’s size unless
-scale or -width says otherwise.
draw.io and Excalidraw output is in beta, not fully tested yet: check the file before relying on
it. It is derived from the laid-out flow model, never from the SVG. Asking
for either on a sequence or class spec is an error: error: render: drawio format is not supported for sequence diagrams, exit 2.
Text art lays the diagram out under its own profile: every position snaps to a character cell, so
node positions differ from the SVG’s even though both are orthogonal. An edge label sits on the
row next to a wire that runs along its row, and may be written over a group frame’s left or right
side when nothing nearer is free. A label that cannot be placed without overwriting other ink is
dropped and reported as the text-label-dropped advisory.
Anchoring on a previous render
Section titled “Anchoring on a previous render”-previous keeps the nodes that survive an edit close to where they were, instead of laying the
whole diagram out from scratch. It takes any of:
- an SVG that diago rendered: it carries its layout in a
<metadata id="diago-layout">element, which is the exact anchor; - that layout carrier as a JSON file on its own;
- the previous spec, which is laid out fresh the way the new render is (under the text profile
for
-format text, else under the theme’s screen profile), so anchoring on an unchanged spec draws what a fresh render draws.
An SVG from an older diago anchors as a best effort. The carrier lists ids only, never labels.
-previous anchors flow and class specs, and a previous spec’s type must match the spec being
rendered. A sequence diagram has no layout to anchor: its render checks that the file is an SVG,
a carrier or a sequence spec, ignores it and warns -previous ignored.
Each version anchored on the render before it:
diago render hello.v1.json > v1.svgdiago render -previous v1.svg hello.v2.json > v2.svgWhen a flat edge falls back to an ordinary edge, the carrier records it, and every render
anchored on that carrier keeps the edge ordinary: its flat-edge-ranked warning then says it was
kept, not that no side route exists. A render without -previous tries the side route again and
decides fresh.
The 10-second timeout
Section titled “The 10-second timeout”A render or diff that has not finished its layout and drawing after 10 seconds is cancelled
and fails. The limit applies to every invocation, and check and import do not lay anything out.
Each git call made to read a REV:PATH has its own 10 seconds. It prints error: the render took longer than 10s and was stopped: split the diagram or simplify it and exits 2.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Success. Advisories and import reports do not change it. |
1 |
The spec is invalid: not JSON, a missing or unknown type, a field of the wrong JSON type, a validation error, a rejected Mermaid line, or, for check -strict, a finding that survived the ignore list. |
2 |
A usage or internal error: an unknown verb or format, a missing file, a git failure reading REV:PATH, a render that fails or runs past 10 seconds, output that cannot be written to stdout. |
A validation error is structured JSON on stderr with a field that names the path into the spec.
This is diago render on a spec whose node has the shape oval:
{ "error": { "type": "validation_error", "errors": [ { "field": "nodes[1].shape", "message": "unknown shape \"oval\"" } ] }}A spec that is not JSON at all has the field "" (in a diff, before or after).
Several errors are collected and returned together. For diff, a field is prefixed before. or
after.. For check -strict, exit 1 means findings
survived the ignore list; the output is the findings, not a JSON error.
stderr formats
Section titled “stderr formats”- Advisories, on
renderanddiff:warning: <rule> <field>: <message>, orwarning: <rule>: <message>for a finding about the whole diagram.checkprints the same lines without thewarning:prefix, on stdout. - Import reports:
warning: import line <n>: <message>. With two inputs the line names the side:warning: import (before) line <n>: <message>,(after)or(previous). - A rejected Mermaid line:
diago <verb>: line <n>: <message>, exit 1. - Anything else that fails:
error: <message>, exit 2. - With
-debug, JSON Lines on stderr as well.
Without -debug, stderr stays empty on a clean render.
diago import
Section titled “diago import”diago import diagram.mmd > spec.json # JSON on stdout, report lines on stderrdiago import < diagram.mmd | diago checkThe dialect is sniffed from the header. The output is the JSON an agent would have written:
two-space indent, edge ids left out for diago to derive, rect left out. Exit 1 on a rejected line (plain text, with
the line number) or on a non-Mermaid input; exit 0 otherwise, even with report lines.
Flowchart (graph or flowchart, with TD, TB, LR, BT or RL):
- Every node bracket form; the links
-->,---,-.->,-.-,==>,===and<-->, with|label|or-- label -->; a trailing;;&fan-out; chains; nestedsubgraph … end(a fourth level is flattened into its depth-3 ancestor and reported); atitle:frontmatter. - Translated and reported: stadium and subroutine shapes become
roundedandrect, doublecircle and trapezoid becomecircleandparallelogram. - Rejected:
classDef,class,style,linkStyle,click,accTitle,accDescr,direction, and an edge whose endpoint is a subgraph.
Sequence (sequenceDiagram):
participantandactorwithas, implicit declaration on first use; the arrows->>,-->>,-)and--);loop,opt,alt/else,par/andandbreakblocks, nested, become fragments over interaction ranges.- Translated and reported:
actorrenders as a participant;+and-marks andactivate/deactivatelines are ignored, because diago computes the activation bars; aNoteis folded into the label of the nearest preceding message in its block, and dropped when there is none; an empty branch or block is dropped. - Rejected:
critical,autonumber,create,destroy,rect,box,link,links,properties,details, and lost-message arrows (-x).
Class (classDiagram):
class X~T~ { … }blocks and bare declarations,<<stereotype>>inside a block or on its own,X : +memberinline members, visibility prefixes,*abstract and$static suffixes,~T~generics, all twelve relation operators with cardinalities and labels (the JSON is written withfromas the subtype, implementer, owner or dependent), anddirection TB|LR|BT|RL.- Rejected:
<-->,()--,note,namespace,cssClassandclick.
Environment variables
Section titled “Environment variables”| Variable | Description |
|---|---|
DIAGO_RESVG_PATH |
Path to the resvg binary, overriding the PATH lookup. PNG only. |
DIAGO_THEME_DIR |
Directory searched for theme files whose name is not built in. A theme name is a plain file name, never a path. Built-in themes always win. See Theme file. |
These are the only two.