Skip to content

CLI reference

nf-metro ships eleven commands. This page covers all of them and every option they accept.

CommandWhat it does
renderRender one or more .mmd files to SVG or interactive HTML
render-manyRender a JSON manifest of render jobs in one process
convertConvert a Nextflow -with-dag mermaid file to nf-metro format
validateCheck a .mmd file for errors without producing output
infoShow what nf-metro parsed and derived from a map
explainShow why the layout engine made each decision
serveServe a live-progress view of one map
serve-multiRun a persistent live server many pipelines can report into
check-mappingCheck a map’s %%metro process: mapping against a pipeline
validate-svgValidate a rendered SVG’s embedded manifest (and its ink)
embed-scriptPrint the embed driver JS for a host page

nf-metro --version prints the installed version. Every command also takes --help.

Most render options have a %%metro directive twin. A flag you pass explicitly overrides the directive.

Render a Mermaid metro map definition to SVG or interactive HTML.

Terminal window
nf-metro render [OPTIONS] INPUT_FILE...

Accepts one or more INPUT_FILEs. Given more than one, they all render in the same process, which amortises interpreter and import startup across the batch, and each writes to its own sibling <input>.<format>. Every file is attempted even if an earlier one fails, successful outputs are kept, and the command exits non-zero if any file failed.

A rejected input, and any other failure, surfaces as a plain error message rather than a traceback. Set NF_METRO_DEBUG=1 to re-raise the original exception instead. An empty file, or one whose graph block holds no stations, is rejected by name rather than drawn.

Most of the options below also have a %%metro directive twin, and a flag you pass explicitly overrides the directive. See the precedence table in the guide.

OptionDefaultDescription
-o, --output PATH<input>.<format>Output file path (only valid with a single INPUT_FILE)
--format [svg|html]svgOutput format: svg, or html for an interactive self-contained page
--from-nextflowoffConvert Nextflow -with-dag mermaid input before rendering
--debug / --no-debugoffShow the debug overlay (ports, hidden stations, edge waypoints)
OptionDefaultDescription
--theme [dark|light|nfcore|nfcore-dark|nfcore-light|seqera|seqera-dark|seqera-light]from style:, else nfcoreVisual theme. A bare brand name (nfcore, seqera) takes the mode from --mode; the suffixed names pin a mode. dark is a legacy alias for nfcore. Takes the same names as its directive twin %%metro style:, but exactly as spelled here: an unknown or wrong-case name exits with an error, where the directive warns and falls back
--mode [light|dark]from mode:, else darkDisplay mode, independent of the brand. Bakes the chosen mode’s palette, so use it for light or dark PNG export. Directive twin: %%metro mode:
--logo PATHnoneLogo image path (must exist; errors on a bad path). Directive twin: %%metro logo:
--title TEXTfrom title:Pipeline title. Directive twin: %%metro title:
--caption TEXTnoneFree-text caption or attribution line rendered bottom-left of the map (e.g. Adapted from Author et al., Journal (Year)). Directive twin: %%metro caption:

--theme light is the transparent embed theme rather than a brand. It has no light/dark pair, so --mode does not apply to it.

OptionDefaultDescription
--legend TEXTautoPosition the legend+logo block: keyword (bl/br/tl/tr/bottom/right/none), <keyword> | canvas, <keyword> | dx,dy, or absolute x,y
--logo-scale FLOAT1.0Scale the logo within the legend block (1.0 = default auto-size)
--legend-min-height FLOAT0Minimum legend content height in pixels (useful for single-line maps where the logo would otherwise be tiny)
--legend-logo-gap FLOATautoHorizontal gap in pixels between the logo and the legend entries
OptionDefaultDescription
--line-spread [bundle|centered|rails]bundleHow lines sharing a station relate vertically: bundle merges them onto one trunk, centered balances the bundle about the midline, rails draws parallel rails with interchange stations. Overrides the graph-wide directive; per-section %%metro line_spread: overrides stay
--x-spacing FLOATautoHorizontal spacing between layers (auto widens from 60 only when wide labels would otherwise collide)
--y-spacing FLOATautoVertical spacing between tracks (auto is derived from the map’s content so captioned icons and dense labels don’t collide)
--section-x-gap FLOAT50Horizontal gap between sections
--section-y-gap FLOAT50Vertical gap between sections
--track-gap FLOAT1Visual gap in pixels (0 to 3) between adjacent line strokes in a bundle, edge to edge rather than centre to centre. 0 means the lines touch; values above 3 are rejected
--fold-threshold INTEGER15Max station-columns a section row may reach before the auto-layout wraps it onto the next row. Raise it to keep a long horizontal trunk on one row
--diamond-style [straight|symmetric]straightFork-join (diamond) layout: straight keeps the top branch on the main track, symmetric fans the branches evenly
--line-order [definition|span]definitionLine ordering for track assignment: definition preserves .mmd order, span gives longest-spanning lines inner tracks
--row-align [content|top]contentSection box vertical sizing within a shared grid row: content hugs each section’s own content, top grows shorter row-mates upward so their box tops and header badges sit flush with the tallest section in the row
--center-ports / --no-center-portsoffCentre inter-section ports on the shorter of the two connected sections, so lines enter and exit at the visual midpoint
--compact-offsets / --no-compact-offsetsoffSize each station only for the lines actually passing through it, rather than reserving a slot for every declared line
--label-angle FLOATtheme default (0)Angle in degrees for station labels (0 = horizontal). Useful for dense trunks where horizontal labels collide
--font-scale FLOAT1.0Scale every text size and the label-width metrics that drive layout spacing
--stroke-scale FLOAT1.0Scale track stroke weight and station pill size, widening bundle spacing, marker clearance, and rail pitch to match
--width INTEGERautoOutput width in pixels
--height INTEGERautoOutput height in pixels

Spacings, scales, --fold-threshold and output dimensions must be greater than 0. The section gaps, --track-gap, --legend-min-height and --legend-logo-gap also accept 0. Every numeric option requires a finite number, so nan and inf are refused. Out of range, the flag exits with an error, while the equivalent %%metro directive warns and keeps the default.

OptionDefaultDescription
--inactive-lines TEXTfrom line: directivesComma-separated line IDs to render inactive: their strokes, chevrons, and legend swatches grey out, as do the stations, labels, and terminus icons touched only by inactive lines. Unknown IDs error. Fully replaces the map’s inactive-marked lines; an empty value forces every line active. Does not edit the .mmd
--animate / --no-animateoffAdd animated balls traveling along the metro lines
--directional / --no-directionaloffDraw static chevrons along each route pointing in the flow direction (source to target)

These carry into the rendered SVG’s manifest and drive live progress. They do not change the drawn map.

OptionDefaultDescription
--auto-process / --no-auto-processoffMap each station to its own id as a default process pattern when it has no explicit %%metro process: directive, so a map whose station ids already name their Nextflow processes lights up live with no per-station mapping. Explicit directives override the default
--process-scope TEXTnoneCommon fully-qualified-name prefix shared by the pipeline’s processes (e.g. NFCORE_RNASEQ:RNASEQ). Each %%metro process: value is then the tail under this scope, joined as <scope>:<tail> and matched literally, so a pasted process path needs no regex. Without a scope, process: values stay regexes
OptionDefaultDescription
--validateoffAfter rendering, fail if the render-geometry guards find a defect in the produced SVG: a route drawn through a station’s label or marker, or two lines collapsed onto one stroke. Tier-A layout-invariant violations stay warnings here; --strict fails on those. SVG output only, and only for a map that keeps its manifest, which the guards read the drawn geometry through
--strict / --no-strictoffTreat a Tier-A layout-invariant violation on the rendered geometry as an error (non-zero exit) instead of a warning
--permissive / --no-permissiveoffDowngrade layout and render guard failures to warnings and render best-effort on whatever geometry was computed, instead of aborting with no output. Overrides --strict

A map that parses with complaints, such as an unknown %%metro directive or a non-LR primary direction, still gets written. So does a layout that widens a gap to fit its routing. Each complaint appears as a bullet in a Warnings: block on stderr. A geometry guard that was downgraded rather than enforced gets its own block, because those name geometry that was drawn anyway and may be defective. Read them differently from a warning about something merely ignored or adjusted.

Flags for producing an SVG to embed in another page or application. The Embedding guide explains when to use each.

OptionDefaultDescription
--responsive / --no-responsiveoffEmit viewBox only (no fixed width/height) for CSS-scalable embedding
--embed-font / --no-embed-fontoffInline a subset of Inter as a base64 @font-face block so the SVG renders identically on any host regardless of installed fonts
--text-to-paths / --no-text-to-pathsoffConvert all text to vector paths, removing font dependencies entirely. Loses selectable text; needs the font extra (pip install "nf-metro[font]")
--bare / --no-bareoffOmit the title and outer padding so the canvas hugs the diagram content (the attribution watermark is kept)
--svg-class-prefix TEXTnonePrefix every SVG presentation class with this string (e.g. myapp produces myapp-nf-metro-station). Use distinct prefixes for each map on a shared page. No effect on the interactive HTML output, which already scopes each map
--no-self-color-schemeoffOmit color-scheme: light dark from the root <svg>. Use when inlining into a host page that owns the theme: the SVG then inherits the page’s color-scheme, so a manual toggle drives light-dark() resolution rather than the viewer’s OS preference
--no-dark-mode-cssoffSuppress the prefers-color-scheme: dark <style> block when a host page manages its own theme and the injected media query would conflict
--no-chrome-cssoffOmit the chrome --nfm-* CSS custom-property <style> block. Colors still render (they are baked as presentation attributes); only live host recoloring is dropped. Needed for raster export, since cairosvg and similar rasterizers cannot parse var()

Every SVG carries the machine-readable data manifest, meaning the <metadata> block and the per-node data-node-* attributes. Opt out per map with %%metro manifest: false. A --manifest/--no-manifest flag pair backs that directive but is deliberately absent from render --help. It is an internal escape hatch for a one-off render, used by nf-metro’s own docs-site rendering. The directive is the supported control.

--format html produces a self-contained .html file with the SVG inlined and a small JS and CSS layer. It has no external dependencies and needs no network:

Terminal window
nf-metro render pipeline.mmd --format html -o pipeline.html

The page supports drag-to-pan, scroll-to-zoom, station hover tooltips and a clickable line legend. Clicking a line isolates it: stations and sections that do not carry that line are hidden, and the view zooms to the bounding box of what remains. Click again, press Esc, or use the Reset button to restore the full view.

The Embed… button opens a panel with copyable inline-HTML, iframe and static-SVG snippets. The Embedding guide explains when to use each one, and covers responsive sizing, font portability, host theming and progress overlays.

Pass --validate to check the drawn SVG after rendering. It exits non-zero if a route is drawn through a station’s label or marker, or if two distinct lines collapse into one stroke where they should run parallel. It reads the geometry as it ends up on the page, after the per-line offsets and label shifts the layout applies, so it catches defects the pre-render checks cannot see:

Terminal window
nf-metro render pipeline.mmd -o pipeline.svg --validate

The guards read the drawn SVG through its embedded manifest, so --validate refuses a map that turns the manifest off with %%metro manifest: false rather than reporting a pass it never checked.

--validate covers those drawn-geometry guards only. A Tier-A layout-invariant violation, such as two stations landing on the same coordinate, is reported as a warning and still renders. Pass --strict to exit non-zero on one, or use nf-metro validate --with-layout to catch it before rendering at all.

To run the same geometry checks on an already-rendered SVG, use nf-metro validate-svg --geometry.

Render multiple metro maps from a JSON manifest in one process, amortising interpreter and import startup across the whole corpus. Output directories are created as needed. On partial failure, successful outputs are kept and the command exits non-zero.

Terminal window
nf-metro render-many MANIFEST_FILE

MANIFEST_FILE is a JSON array of render jobs. Each job is an object with the required input and output keys, plus any subset of the render options expressed as JSON keys:

KeyDescription
inputPath to the source .mmd file (required)
outputPath for the output file (required)
format"svg" (default) or "html"
themeTheme name (nfcore, light, seqera, and the mode-suffixed variants)
mode"light" or "dark"; bakes a concrete palette
debugShow the debug overlay (default false)
logoLogo image path (overrides %%metro logo:)
line_spread"bundle", "centered", or "rails"
legendLegend position keyword or coordinate
from_nextflowConvert from a Nextflow DAG first (default false)
titlePipeline title override
responsiveEmit viewBox-only SVG (default false)
embed_fontInline the Inter @font-face subset (default false)
text_to_pathsConvert text to vector paths (default false)
svg_class_prefixPrefix for SVG presentation classes
no_self_color_schemeOmit color-scheme on the root <svg> (default false)
no_dark_mode_cssSuppress the prefers-color-scheme block (default false)
no_chrome_cssOmit the chrome CSS custom properties (default false)
bareOmit the title and outer padding (default false)
validateRun the render-geometry guards (default false)
inactive_linesLine IDs to render inactive, as a comma-separated string or a JSON list. Omit the key to use the map’s own inactive-by-directive lines; give [] to force every line active
layout_optionsObject of layout overrides, e.g. {"manifest": false, "x_spacing": 60}
[
{ "input": "examples/rnaseq_auto.mmd", "output": "out/rnaseq.svg" },
{
"input": "examples/sarek.mmd",
"output": "out/sarek.svg",
"mode": "light",
"layout_options": { "x_spacing": 60 }
}
]

Convert a Nextflow -with-dag mermaid file to nf-metro .mmd format. Render the output with nf-metro render, or hand-tune it first.

Terminal window
nf-metro convert [OPTIONS] INPUT_FILE
OptionDefaultDescription
-o, --output PATHstdoutOutput .mmd file path
--title TEXTnonePipeline title for the converted output

See Importing from Nextflow for details and examples.

Check a .mmd file for errors without producing output. The bare command runs graph-semantic checks: that every edge references a defined line, that every section points at stations that exist, and that the graph is acyclic.

Terminal window
nf-metro validate [OPTIONS] INPUT_FILE
OptionDefaultDescription
--with-layoutoffAlso run the layout engine with its full invariant suite, reporting any layout failure as an error instead of a traceback
--strictoffTreat warnings (e.g. a non-LR primary direction) as errors

A map with no stations is reported as a warning here, because render refuses to draw one.

Show information about a parsed map: its sections, lines, stations and edges. The default output is a stable human-readable summary.

Terminal window
nf-metro info [OPTIONS] INPUT_FILE
OptionDefaultDescription
--jsonoffEmit the full introspection as JSON, for scripting
--verboseoffAdd the section dependency graph, per-line routes, inferred auto-layout defaults, and synthetic ports and junctions to the text output

Parse warnings print as a Warnings: block on stderr, which keeps the summary on stdout clean. --verbose and --json carry them in the report itself instead.

Style: reports the theme the map resolves to, which is the name render --theme accepts.

Explain why nf-metro made each layout decision. It names the rule that fired for each inferred choice, covering section direction, port sides, and fold and row layout, and for each synthetic element the engine inserted, such as fan-out junctions and bypass-V stations. It pairs with nf-metro info, which shows what was built.

Terminal window
nf-metro explain [OPTIONS] INPUT_FILE
OptionDefaultDescription
--jsonoffEmit the full explanation as JSON
--section SECTION_IDnoneRestrict output to decisions involving this section
--station STATION_IDnoneRestrict output to decisions involving this station

Serve a live-progress view of a metro map. INPUT_FILE may be a .mmd source or an already-rendered nf-metro SVG. The map is rendered once and served at http://HOST:PORT/. Point a Nextflow run’s weblog at the events endpoint to light up stations as tasks run.

Terminal window
nf-metro serve [OPTIONS] INPUT_FILE [-- LAUNCH_CMD...]

Stations are tied to processes with %%metro process: directives in the map, so only mapped stations change state. Live progress covers the event format, the overlay styles and the endpoints.

OptionDefaultDescription
--port INTEGER8080Port to listen on
--host TEXT127.0.0.1Interface to bind. The default is local only; use 0.0.0.0 to accept connections from other hosts
--theme [dark|light|nfcore|nfcore-dark|nfcore-light|seqera|seqera-dark|seqera-light]from style:Visual theme, the same choices as render --theme
--overlay [ring|pulse|dot|led]ringStatus-overlay style shown until a viewer picks another in the page
--token TEXTnoneIf set, /events POSTs must supply ?token=... or an X-Metro-Token header
--openoffOpen the live page in a browser
--shutdown-after-completeoffStop the server shortly after the run’s completed or error event (or after the launched command exits)
--shutdown-grace FLOAT10Seconds to keep the map up after the run finishes, with --shutdown-after-complete

With an SVG input the map is served exactly as drawn, so --theme applies only to a .mmd input.

Passing a LAUNCH_CMD after -- starts the run in one step with the weblog wired up automatically:

Terminal window
nf-metro serve map.mmd --open --shutdown-after-complete -- \
nextflow run my/pipeline -profile docker

Without a launch command, point the run at the server yourself:

Terminal window
nextflow run ... -with-weblog http://localhost:8080/events

Run a persistent live server that many pipelines can report into. It starts with no map, unlike serve. A pipeline registers its map by POSTing the .mmd to /maps, then sends weblog events to the run’s /r/<id>/events endpoint. The index at http://HOST:PORT/ lists every run with a live status.

Terminal window
nf-metro serve-multi [OPTIONS]
OptionDefaultDescription
--port INTEGER8080Port to listen on
--host TEXT127.0.0.1Interface to bind. The default is local only; use 0.0.0.0 to accept connections from other hosts
--theme [dark|light|nfcore|nfcore-dark|nfcore-light|seqera|seqera-dark|seqera-light]nfcoreVisual theme, the same choices as render --theme
--overlay [ring|pulse|dot|led]ringStatus-overlay style shown until a viewer picks another in the page
--token TEXTnoneIf set, POSTs to /maps and /r/*/events must supply ?token=... or an X-Metro-Token header

The nf-metro Nextflow plugin’s metro.server mode does the register-and-emit automatically. See Live progress.

Check a map’s %%metro process: mapping against the pipeline’s real processes. It reports processes the map can’t show, called drift, and station patterns that match nothing, called stale. It exits non-zero if it finds either, so CI can gate on map fidelity.

Terminal window
nf-metro check-mapping [OPTIONS] INPUT_FILE
OptionDefaultDescription
--dag PATHnoneNextflow -with-dag mermaid file; process names are read from its stadium nodes
--processes PATHnoneNewline-delimited process names (e.g. captured from a run). Authoritative alternative to --dag
--ignore TEXTnoneRegex for processes deliberately left unmapped (plumbing). Repeatable

Validate a rendered SVG’s embedded manifest against the manifest JSON Schema.

Terminal window
nf-metro validate-svg [OPTIONS] SVG_FILE

Schema validation needs jsonschema, which is not a runtime dependency. It ships in the validate extra:

Terminal window
pip install "nf-metro[validate]"
OptionDefaultDescription
--geometryoffAlso run the artifact-only render-geometry guards on the drawn ink (label strikes and non-consumer marker crossings), not just the manifest schema. The offset-collapse check needs the engine’s assigned offsets and runs only via render --validate

Print the attachMetroMap() embed driver JS to stdout. Load it on a host page alongside an nf-metro SVG to get the documented interactive API.

Terminal window
nf-metro embed-script [OPTIONS]
OptionDefaultDescription
-o, --output PATHstdoutWrite to a file instead of stdout

See the embed contract for the driver API.