# Command line

The package ships a CLI for use without writing any JavaScript:

<PackageManagers type="dlx" pkg="sfn-diagram" pkgManagers={['npm', 'pnpm', 'yarn', 'bun']} args="state.asl.json --format svg -o diagram.svg" />
<PackageManagers type="dlx" pkg="sfn-diagram" pkgManagers={['npm', 'pnpm', 'yarn', 'bun']} args="state.asl.json --format mermaid > diagram.mmd" />

```bash
cat state.asl.json | npx sfn-diagram - --format svg
```

Piped 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](/guides/configuration/#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](#linting) |
| `-h`, `--help` / `-v`, `--version` | Show help / version and exit |

## Diff and execution overlays from the CLI

```bash
# Highlight what changed between two revisions of a definition
npx sfn-diagram head.asl.json --diff base.asl.json -o diff.svg
npx sfn-diagram head.asl.json --diff base.asl.json --format mermaid > diff.mmd

# Colour a diagram by what actually happened in a run
aws stepfunctions get-execution-history --execution-arn "$ARN" > history.json
npx sfn-diagram state.asl.json --execution history.json -o run.svg
```

Both 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](/reference/index/functions/generatediff/)
and [generateExecution](/reference/index/functions/generateexecution/) for the
programmatic equivalents.

CloudFormation/SAM/CDK templates work as input too — see [Extracting ASL from a CDK/CloudFormation template](/reference/cfn/functions/extractaslfromtemplate/).

> **`--format png` needs the optional `@resvg/resvg-js` peer.** It is not installed by default. With `npx`, run `npx --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](#docker), which ships it preinstalled.

## Linting

`--check` runs [`lintAsl`](/reference/index/functions/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:

```bash
npx sfn-diagram state.asl.json --check
```

```
error   /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 warning
```

Each 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`

`sfn-diagram comment gitlab` posts (or updates) a diagram/diff on a GitLab merge
request from CI — see [GitLab CI](/ecosystem/gitlab/) for the full workflow, the
options, and the Mermaid size limit it works around.

```bash
sfn-diagram comment gitlab --help
```

## 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:

```bash
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.png
```

Tags: `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

Each GitHub release also attaches single-file executables for Linux (x64, arm64),
macOS (Apple silicon, Intel), and Windows (x64) that need no Node.js:

```bash
brew install yusufaf/tap/sfn-diagram
# or download sfn-diagram-<os>-<arch> from the releases page and chmod +x it
```

They 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](/guides/other-languages/).