CLI reference

The puml CLI is the canonical reference implementation of the engine. Everything the studio editor will eventually do in your browser, the CLI already does on disk.

Modes at a glance

ModeTriggerOutput
Render single filepuml input.pumlwrites input.svg (or .png with --format)
Render from stdincat x.puml | puml - or | pumlwrites SVG to stdout
Check / lintpuml --check input.pumlexit code only, diagnostics on stderr
Multi-input lintpuml --check --lint-input ...aggregated lint report on stdout
Preprocessor dumppuml --preproc input.pumlpreprocessed source on stdout
Markdown fence extractionpuml --from-markdown notes.mdrenders each fenced diagram block
AST / model / scene dumppuml --dump ast input.pumlJSON on stdout
Multi-page modepuml --multi input.pumlnewpage splits into numbered files / JSON
Language serverpuml-lspLSP over stdio

Inputs

  • INPUT — a file path.
  • - — read from stdin explicitly.
  • omitted — read from stdin implicitly when stdin is piped (TTY stdin prints help).

Flags

--format svg|png             output format (default: svg)
--style puml|plantuml        chrome style mode (default: puml)
--dpi FLOAT                  PNG rasterization DPI (default: 96)
--check                      parse + normalize only, no render output
--check-syntax               PlantUML-compatible alias for --check
--preproc                    dump source after !include and macro expansion
--lint-input INPUT           repeatable check input (check mode only)
--lint-glob GLOB             repeatable glob-expanded check input
--lint-report human|json     lint summary report format (default: human)
--dump ast|model|scene       dump pipeline JSON instead of rendering
--multi                      allow multiple stdin diagrams / pages
--from-markdown              treat input as markdown, extract fenced blocks
--diagnostics human|json     diagnostics output format (default: human)
--stdrpt                     one-line diagnostics: severity\tcode\tfile:line:col\tmessage
--dialect auto|plantuml|mermaid|picouml
                             select frontend input dialect; auto uses file extensions and fences
--compat strict|extended     semantic compatibility policy (default: strict)
--include-root DIR           resolve `!include` from this root for stdin
--allow-url-includes         allow URL includes for trusted compatibility runs
--no-url-includes            compatibility no-op; URL includes are disabled by default
--duration                   print elapsed wall time to stderr
--quiet / -q                 suppress non-error stderr
--verbose / -v               emit per-stage parse/normalize/render timings
--fail-on-warn               exit 1 if any warnings are emitted
--failfast2                  remap validation exit code 1 → 2 (PlantUML diagram-error convention)
--overwrite                  no-op (outputs are always overwritten)
--htmlcss                    no-op PlantUML compatibility flag for HTML output
--charset UTF-8              no-op (only UTF-8 is supported)
--output / -o PATH           write to PATH instead of the derived path
--metadata                   print JSON metadata (title, family, page count) to stdout
--metadata-output FILE       write --metadata JSON to FILE instead of stdout
--extract                    split multi-diagram .puml into one file per @startuml block
--pattern REGEX              filter lint/check file selection by regex over resolved paths

Frontend dialects

# explicit dialect (default is auto)
puml --dialect plantuml input.puml
puml --dialect mermaid input.mmd
puml --dialect picouml input.picouml
  • auto uses input hints first: .picouml files and picouml markdown fences route through the PicoUML adapter, while mermaid fences route through the Mermaid adapter.
  • plantuml parses PlantUML-compatible source through the shared pipeline.
  • mermaid accepts sequenceDiagram, flowchart/graph, classDiagram, stateDiagram/stateDiagram-v2, and erDiagram.
  • picouml routes through PicoUML adapter rewrites first, then the same parser, model, layout, and renderer as PlantUML-compatible inputs.

Includes and remote sources

The native CLI supports URL includes for PlantUML compatibility when explicitly enabled: !include https://..., !includeurl, URL !include_many, URL !import, and file:// targets can fetch or read source and cache HTTP(S) responses locally. Pass --allow-url-includes only for trusted inputs; without it, URL targets fail with E_INCLUDE_URL_DISABLED.

Embedded surfaces are stricter by design. The LSP does not fetch remote includes while publishing diagnostics or previews, the WASM/browser renderer rejects filesystem and URL includes, and bundled MCP/agent tools keep URL includes disabled unless a tool call explicitly sets allow_url_includes: true. See the URL include policy for the surface-by-surface contract.

Output paths

  • Single diagram from file → <input-stem>.svg (or .png).
  • Single diagram from stdin → SVG on stdout (or PNG bytes with --format png).
  • Multi-page file inputs → numbered files <stem>-1.svg, <stem>-2.svg, …
  • Multi-page stdin requires --multi; with it, stdout is a deterministic JSON array [{"name": "...", "svg": "..."}, ...]. Only SVG is supported in this mode.
  • ignore newpage collapses multi-page splits into a single output.

Exit codes

CodeMeaning
0success
1validation or usage failure
2I/O failure
3internal failure

Diagnostics

  • Errors and warnings include line / column and caret snippets when source spans are available.
  • Unsupported skinparam keys and !theme directives emit deterministic non-fatal warnings on stderr.
  • --diagnostics json emits a stable schema:
{
  "schema": "puml.diagnostics",
  "schema_version": 1,
  "diagnostics": [
    {
      "code": "E_PICOUML_MARKER_MIXED",
      "severity": "error",
      "message": "...",
      "span": { "start": 12, "end": 24 },
      "line": 2, "column": 1,
      "snippet": "@startpicouml",
      "caret": "^^^^^^^^^^^^^"
    }
  ]
}

Stream contract

Always:

  • Render / --check, --check-syntax, and --dump payloads go to stdout.
  • Diagnostics (human or JSON) go to stderr.
  • Lint batch mode keeps diagnostics on stderr and prints the lint summary on stdout.