Skip to content

CLI reference

nf-metro ships eleven commands.

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 drawn geometry
embed-scriptPrint the embed driver JS for a host page

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

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 amortizes interpreter and import startup across the batch.
  • 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 in this section have a %%metro directive twin. An explicit flag 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, and 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. Use it for light or dark PNG export. Directive twin: %%metro mode:
--logo PATHnoneLogo image path (errors if the path does not exist). 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 (for example, Adapted from Author et al., Journal (Year)). Directive twin: %%metro caption:

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

OptionDefaultDescription
--legend TEXTautoPosition the legend and 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 do not 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 center to center. 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-portsoffCenter inter-section ports on the shorter of the two connected sections. Lines then 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

Numeric options are validated as follows:

  • 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, and nan and inf are refused.

A flag given an out-of-range value 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 gray 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. A map whose station ids already name their Nextflow processes then 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 (for example, NFCORE_RNASEQ:RNASEQ). Each %%metro process: value is then the tail under this scope, joined as <scope>:<tail> and matched literally. A pasted process path then 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, and --strict fails on those. SVG output only, and only for a map that keeps its manifest. The guards read the drawn geometry through that manifest
--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, is still written. So is 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 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, and 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 (for example, 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, and 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, baked as presentation attributes, and only live host recoloring is dropped. Needed for raster export, because 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 select Reset to restore the full view.

The Embed… button opens a panel with copyable inline-HTML, iframe, and static-SVG snippets. The Embedding guide 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. It therefore catches defects the pre-render checks cannot see:

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

Because the guards read the drawn SVG through its embedded manifest, --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 the map 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, amortizing 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, for example {"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 (for example, 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 rather than into the stdout summary. --verbose and --json carry them in the report itself instead.

Style: reports the theme the map resolves to, using the same 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. It does the same 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...]

%%metro process: directives in the map tie stations to processes, and 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. --theme therefore applies only to a .mmd input.

Passing a LAUNCH_CMD after -- starts the run in one step with the weblog configured 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 metro.server mode of the nf-metro Nextflow plugin 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 cannot show, called drift, and station patterns that match nothing, called stale. It exits non-zero if it finds either. CI can therefore 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, for example 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 only 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.