Command line
The package ships a CLI for use without writing any JavaScript:
npx sfn-diagram state.asl.json --format svg -o diagram.svgpnpx sfn-diagram state.asl.json --format svg -o diagram.svgyarn dlx sfn-diagram state.asl.json --format svg -o diagram.svgbunx sfn-diagram state.asl.json --format svg -o diagram.svgnpx sfn-diagram state.asl.json --format mermaid > diagram.mmdpnpx sfn-diagram state.asl.json --format mermaid > diagram.mmdyarn dlx sfn-diagram state.asl.json --format mermaid > diagram.mmdbunx sfn-diagram state.asl.json --format mermaid > diagram.mmdcat state.asl.json | npx sfn-diagram - --format svgPiped through any runner works the same way — swap npx for pnpm dlx, yarn dlx, or bunx.
| Flag | Description |
|---|---|
--format <svg|mermaid|png|html> |
Output format (default: svg) |
-o, --output <path> |
Output file (required for png; stdout otherwise) |
--theme <light|dark> |
Color theme for SVG/PNG/HTML (default: light) |
--layout <TB|LR|RL|BT> |
Graph direction (default: TB) |
--hide-catch |
Drop error-handler (Catch) branches |
--hide-variables |
Drop the $var annotations for ASL Assign blocks |
--show-icons |
Draw AWS service icons on Task states |
--icon-position <left|top|right> |
Icon placement relative to the label (default: left) |
--icon-size <pixels> |
Icon size in pixels (default: 24) |
--diff <baseline> |
Compare the input (head) against a baseline definition |
--execution <history.json> |
Overlay a GetExecutionHistory result on the diagram |
--resolve-cfn |
Treat the input as a CloudFormation/SAM/CDK template |
--resource <logicalId> |
State machine to extract when the template has several |
--check |
Lint the definition instead of drawing it — see Linting |
-h, --help / -v, --version |
Show help / version and exit |
Diff and execution overlays from the CLI
Section titled “Diff and execution overlays from the CLI”# Highlight what changed between two revisions of a definitionnpx sfn-diagram head.asl.json --diff base.asl.json -o diff.svgnpx sfn-diagram head.asl.json --diff base.asl.json --format mermaid > diff.mmd
# Colour a diagram by what actually happened in a runaws stepfunctions get-execution-history --execution-arn "$ARN" > history.jsonnpx sfn-diagram state.asl.json --execution history.json -o run.svgBoth flags support --format svg, --format mermaid, and --format html only, and
cannot be combined with each other. The change/status summary is written to stderr,
so the diagram on stdout still pipes cleanly:
Diff summary: Added: NewStep Modified: StepB Removed: StepC Unchanged: 1--execution accepts either a full GetExecutionHistory response ({"events": [...]})
or a bare events array. See generateDiff
and generateExecution for the
programmatic equivalents.
CloudFormation/SAM/CDK templates work as input too — see Extracting ASL from a CDK/CloudFormation template.
--format pngneeds the optional@resvg/resvg-jspeer. It is not installed by default. Withnpx, runnpx --package sfn-diagram --package @resvg/resvg-js sfn-diagram …; in a project,npm install @resvg/resvg-js. Without it the CLI exits with an actionable error. Or skip the install entirely with the Docker image, which ships it preinstalled.
Linting
Section titled “Linting”--check runs lintAsl on the input and prints every
finding to stderr instead of a diagram. The exit code is 1 when any finding is an
error, 0 otherwise, so it drops straight into a pre-commit hook or CI step:
npx sfn-diagram state.asl.json --checkerror /States/Ship/Next State "Ship" sets both "End: true" and "Next" [end-with-next]warning /States/Audit State "Audit" is unreachable from StartAt "Validate" [unreachable-state]1 error, 1 warningEach line is severity, a JSON Pointer to the offending value, the message, and the
rule code. --resolve-cfn / --resource work the same way they do for rendering;
--check cannot be combined with --diff, --execution or --output.
comment gitlab
Section titled “comment gitlab”sfn-diagram comment gitlab posts (or updates) a diagram/diff on a GitLab merge
request from CI — see GitLab CI for the full workflow, the
options, and the Mermaid size limit it works around.
sfn-diagram comment gitlab --helpDocker
Section titled “Docker”A prebuilt image is published to GitHub Container Registry with the PNG rasterizer preinstalled, so --format png works out of the box — no browser, no extra install:
docker run --rm -v "$PWD":/work ghcr.io/yusufaf/sfn-diagram:latest \ /work/state.asl.json --format svg -o /work/diagram.svg
docker run --rm -v "$PWD":/work ghcr.io/yusufaf/sfn-diagram:latest \ /work/state.asl.json --format png -o /work/diagram.pngTags: latest, <major>, <major>.<minor>, <major>.<minor>.<patch>.
PNG text is rendered with Liberation Sans, which the image ships. To use your own fonts, mount them and point the renderer at them with SFN_DIAGRAM_PNG_FONT_DIRS (a :-separated list of directories) or SFN_DIAGRAM_PNG_FONT_FAMILY.
Standalone binary
Section titled “Standalone binary”Each GitHub release also attaches single-file executables for Linux (x64, arm64), macOS (Apple silicon, Intel), and Windows (x64) that need no Node.js:
brew install yusufaf/tap/sfn-diagram# or download sfn-diagram-<os>-<arch> from the releases page and chmod +x itThey support every format except png: the native rasterizer it needs cannot be
bundled into a single-file executable. Use the Docker image above or the npm
package with @resvg/resvg-js installed. See
Use from Python, Go, Java, and other languages.