Skip to content

CLI Reference

The @pxdiff/cli package is the main entry point for visual regression testing with pxdiff.

Terminal window
npm install -g @pxdiff/cli
Section titled “Interactive login (recommended for local development)”
Terminal window
pxdiff login

Opens your browser to authenticate via GitHub. After login, link a project to your directory:

Terminal window
pxdiff project set myorg/myproject

For CI environments, use a project-scoped API key. Pass it via --api-key or set PXDIFF_API_KEY:

Terminal window
export PXDIFF_API_KEY=pxd_your_key_here

API keys take precedence over stored login credentials.

Capture and diff a Storybook — either from a static build (cloud capture) or a running dev server (local Docker capture).

Terminal window
pxdiff storybook <dir> [options] # static build → cloud capture
pxdiff storybook --port <port> [options] # running dev server → local Docker capture

Either a static build directory (<dir>) or --port is required.

ArgumentDescription
dirPath to the static Storybook build directory
FlagTypeDefaultDescription
--portstringPort of a running Storybook dev server. Captures via a local Linux Docker runner and follows normal mode detection (CI → CI mode, otherwise local mode). Use --local or --ci to override. Requires Docker. Not supported with --only-changed.
--suitestring"default"Suite name for grouping snapshots
--filterstringGlob pattern to filter discovered stories (e.g. "Button*", "**/primary")
--auto-baselinebooleanfalseSet baselines from captured screenshots (no diff)
--auto-approvebooleanfalseAutomatically approve all changes and set baselines
--skip-diffbooleanfalseSkip automatic diff after capture
--statusbooleanfalsePost a GitHub check run and exit 0 (delegates pass/fail to the check run)
--thresholdstringDiff threshold 0.0–1.0
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseRun in local mode (also set via PXDIFF_LOCAL=true)
--cibooleanfalseForce CI mode (strict auth, GitHub check runs)
--frameworkstringFramework hint applied to all targets
--branchstringBranch name (auto-detected from git)
--commitstringCommit hash (auto-detected from git)
--only-changedbooleanfalseOnly capture stories affected by code changes (requires --stats-json Storybook build). Static-build path only — not supported with --port.
--outputstring"text"Output format: text or json
--api-keystringAPI key (falls back to PXDIFF_API_KEY)
--api-urlstringAPI URL (falls back to PXDIFF_API_URL)

Static build workflow (<dir>):

  1. Tars and gzips the Storybook directory
  2. Uploads the archive to pxdiff
  3. Discovers stories automatically
  4. Explodes stories into capture targets (respecting modes, viewports, parameters)
  5. Filters targets if --filter is set
  6. If --only-changed, traces the Storybook module graph to identify affected stories and skips unchanged ones
  7. Creates the capture on the pxdiff fleet

Local dev server workflow (--port):

  1. Checks that Docker is available and detects the installed Playwright version
  2. Pulls or builds a matching pxdiff-runner container image
  3. Creates a session-scoped capture using the detected mode
  4. Runs Chromium inside the container, hitting your dev server at http://host.docker.internal:<port>
  5. Uploads captured snapshots to the session
  6. Runs the diff locally (unless --skip-diff / --auto-baseline)

In local mode, captures are ephemeral and scoped to you — they do not update shared baselines or post CI check runs. In CI mode, the --port path can post CI results while still using the local Docker runner for browser rendering.

Terminal window
# Static build
pxdiff storybook ./storybook-static
# Running dev server (Storybook's default port)
pxdiff storybook --port 6006
# Filter to specific stories
pxdiff storybook ./storybook-static --filter "Button*" --suite ui
# JSON output for CI parsing
pxdiff storybook ./storybook-static --output json

Capture and diff a Ladle catalog — either from a static build (cloud capture) or a running dev server (local Docker capture).

Terminal window
pxdiff ladle <dir> [options] # static build → cloud capture
pxdiff ladle --port <port> [options] # running dev server → local Docker capture

Either a static build directory (<dir>) or --port is required.

ArgumentDescription
dirPath to the static Ladle build directory
FlagTypeDefaultDescription
--portstringPort of a running Ladle dev server. Captures via a local Linux Docker runner and follows normal mode detection (CI → CI mode, otherwise local mode). Use --local or --ci to override. Requires Docker.
--suitestring"default"Suite name for grouping snapshots
--filterstringGlob pattern to filter discovered stories (e.g. "Badge*", "*--primary")
--auto-baselinebooleanfalseSet baselines from captured screenshots (no diff)
--auto-approvebooleanfalseAutomatically approve all changes and set baselines
--skip-diffbooleanfalseSkip automatic diff after capture
--statusbooleanfalsePost a GitHub check run and exit 0 (delegates pass/fail to the check run)
--thresholdstringDiff threshold 0.0–1.0
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseRun in local mode (also set via PXDIFF_LOCAL=true)
--cibooleanfalseForce CI mode (strict auth, GitHub check runs)
--branchstringBranch name (auto-detected from git)
--commitstringCommit hash (auto-detected from git)
--outputstring"text"Output format: text or json
--api-keystringAPI key (falls back to PXDIFF_API_KEY)
--api-urlstringAPI URL (falls back to PXDIFF_API_URL)

Static build workflow (<dir>):

  1. Tars and gzips the Ladle build directory
  2. Uploads the archive to pxdiff
  3. Discovers stories from meta.json
  4. Explodes stories into capture targets
  5. Filters targets if --filter is set
  6. Creates the capture on the pxdiff fleet

Local dev server workflow (--port):

  1. Checks that Docker is available and detects the installed Playwright version
  2. Pulls or builds a matching pxdiff-runner container image
  3. Creates a session-scoped capture using the detected mode
  4. Runs Chromium inside the container, hitting your dev server at http://host.docker.internal:<port>
  5. Uploads captured snapshots to the session
  6. Runs the diff locally (unless --skip-diff / --auto-baseline)

In local mode, captures are ephemeral and scoped to you — they do not update shared baselines or post CI check runs. In CI mode, the --port path can post CI results while still using the local Docker runner for browser rendering.

Terminal window
# Static build
pxdiff ladle ./build
# Running dev server (Ladle's default port)
pxdiff ladle --port 61000
# Filter to specific stories
pxdiff ladle ./build --filter "Badge*" --suite components
# JSON output for CI parsing
pxdiff ladle ./build --output json

Ladle parameters: You can control capture behavior per-story using the meta.pxdiff field in your Ladle stories:

export const MyStory = () => <Component />;
MyStory.meta = {
pxdiff: {
delay: 500, // Wait 500ms before capture
selector: ".wrapper", // Capture specific element
cropToViewport: true, // Crop to viewport bounds
ignoreSelectors: [".timestamp"], // Hide dynamic elements
disable: false, // Set true to skip this story
},
};

Submit screenshot targets from a JSON targets file for capture via the pxdiff fleet.

Terminal window
pxdiff capture <targets-file> [options]
ArgumentDescription
targets-filePath to JSON file containing capture targets (required)
FlagTypeDefaultDescription
--suitestring"default"Suite name
--auto-baselinebooleanfalseSet baselines from captured screenshots (no diff)
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseLocal mode
--frameworkstringFramework hint for all targets
--branchstringBranch name (auto-detected)
--commitstringCommit hash (auto-detected)
--outputstring"text"text or json
--api-keystringAPI key
--api-urlstringAPI URL

The targets file is a JSON array of objects:

[
{
"name": "homepage",
"url": "https://your-app.com",
"viewport": { "width": 1280, "height": 720 }
},
{
"name": "mobile-homepage",
"url": "https://your-app.com",
"viewport": { "width": 375, "height": 812 }
}
]

Upload a directory of pre-existing PNG files as a capture. This is the “bring your own screenshots” workflow.

Terminal window
pxdiff upload <directory> [options]
ArgumentDescription
directoryDirectory containing .png files (required)
FlagTypeDefaultDescription
--suitestring"default"Suite name
--auto-baselinebooleanfalseSet baselines from captured screenshots (no diff)
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseLocal mode
--branchstringBranch name (auto-detected)
--commitstringCommit hash (auto-detected)
--api-keystringAPI key
--api-urlstringAPI URL

Snapshot names are derived from filenames (minus the .png extension).

Terminal window
pxdiff upload ./screenshots --suite e2e

Compare a capture against baselines and produce a diff report.

Terminal window
pxdiff diff [options]
FlagTypeDefaultDescription
--suitestring"default"Suite name
--head-capturestringHead capture ID (auto-detected from current commit if omitted)
--base-capturestringBase capture ID for capture-vs-capture comparison
--baseline-refstringBaseline ref to compare against (auto-resolved if omitted)
--auto-approvebooleanfalseAutomatically approve all changes and set baselines
--thresholdstringDiff threshold 0.01.0
--anti-aliasingstringEnable anti-aliasing detection (true or false)
--manifeststringComma-separated snapshot names to include
--target-refstringTarget ref for resolution (repeatable)
--outputstring"text"text or json
--api-keystringAPI key
--api-urlstringAPI URL

Exit codes:

  • 0 — No changes detected
  • 1 — Changes detected (diff found)
  • 2 — Error
Terminal window
# Auto-detect head capture from current git commit
pxdiff diff --suite storybook
# Explicit capture-vs-capture
pxdiff diff --head-capture cap_abc --base-capture cap_xyz
# Custom threshold
pxdiff diff --suite e2e --threshold 0.1

Wrap a command with a pxdiff session. Auto-detects whether to run in CI mode or local mode based on the CI environment variable.

Terminal window
pxdiff run [options] -- <command...>
pxdiff [options] -- <command...> # shorthand (same behavior)

pxdiff -- <cmd> is shorthand for pxdiff run -- <cmd>.

FlagTypeDefaultDescription
--cibooleanForce CI mode (overrides auto-detection)
--localbooleanForce local mode (overrides auto-detection)
--auto-approvebooleanfalseAuto-approve changed snapshots
--refstringBaseline ref (sets PXDIFF_BASELINE_REF)
--dockerstring/booleanRun inside Docker for consistent rendering. Optionally specify a custom image.
--api-keystringAPI key
--api-urlstringAPI URL

Everything after -- is the command to run. pxdiff sets PXDIFF_SESSION_ID, PXDIFF_API_KEY, and PXDIFF_API_URL in the child process environment. Suite names come from your test plugins (Playwright, Vitest, Cypress) — not from the CLI.

Mode auto-detection: When the CI environment variable is set (true in GitHub Actions, GitLab CI, and most CI providers), pxdiff runs in CI mode — creating GitHub check runs and managing the session lifecycle. Otherwise, it runs in local mode — ephemeral baselines, no GitHub integration. Use --ci or --local to override.

Terminal window
# Run tests (auto-detects CI vs local)
pxdiff -- npx playwright test
# Explicit subcommand form (equivalent)
pxdiff run -- npx playwright test
# Run inside Docker for consistent cross-platform rendering
pxdiff --docker -- npx playwright test
# Force local mode in CI (e.g., for personal testing on CI runners)
pxdiff --local -- npm test
# Auto-approve against a specific baseline ref
pxdiff --auto-approve --ref main -- npm test

Workflow:

  1. Generates a session ID and spawns your command with pxdiff environment variables injected
  2. Plugins upload screenshots and create diffs per-suite using the shared session ID
  3. On exit, completes all diffs in the session and (in CI mode) posts GitHub check runs

Approve changed snapshots in a diff to update baselines.

Terminal window
pxdiff approve <diffId> [options]
ArgumentDescription
diffIdThe diff ID to approve (required)
FlagTypeDefaultDescription
--snapshotstringSnapshot name to approve (repeatable)
--allbooleanfalseApprove all changed snapshots
--api-keystringAPI key
--api-urlstringAPI URL

You must specify either --snapshot (one or more) or --all.

Terminal window
# Approve specific snapshots
pxdiff approve diff_abc --snapshot button-primary --snapshot header
# Approve everything
pxdiff approve diff_abc --all

Revoke approval for snapshots in a diff, reverting baseline updates.

Terminal window
pxdiff revoke <diffId> [options]
ArgumentDescription
diffIdThe diff ID to revoke (required)
FlagTypeDefaultDescription
--snapshotstringSnapshot name to revoke (repeatable)
--allbooleanfalseRevoke all approved snapshots
--api-keystringAPI key
--api-urlstringAPI URL

The following first-class commands are read-only inspection commands. They default to human-readable terminal output and support --output json for automation. JSON output is the stable CLI contract; human-readable output is intended for people.

List suites in the current project.

Terminal window
pxdiff suites list [options]
FlagTypeDefaultDescription
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff suites list
pxdiff suites list --output json

List existing diff reports for a suite. This does not compare screenshots or create a new diff.

Terminal window
pxdiff diffs list --suite <suite> [options]
FlagTypeDefaultDescription
--suitestringSuite name (required)
--branchstringFilter by branch. When omitted, returns diffs for all branches.
--limitstringMaximum number of diffs to return
--offsetstringPagination offset
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff diffs list --suite storybook
pxdiff diffs list --suite storybook --branch main
pxdiff diffs list --suite storybook --output json

Inspect an existing diff report.

Terminal window
pxdiff diffs get <diffId> [options]
ArgumentDescription
diffIdThe diff ID to inspect (required)
FlagTypeDefaultDescription
--summarybooleanfalseFetch lightweight snapshot summary instead of image details
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff diffs get diff_abc
pxdiff diffs get diff_abc --summary
pxdiff diffs get diff_abc --summary --output json

Inspect a capture and its snapshots.

Terminal window
pxdiff captures get <captureId> [options]
ArgumentDescription
captureIdThe capture ID to inspect (required)
FlagTypeDefaultDescription
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff captures get cap_abc
pxdiff captures get cap_abc --output json

List baseline refs for a suite.

Terminal window
pxdiff baselines list --suite <suite> [options]
FlagTypeDefaultDescription
--suitestringSuite name (required)
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff baselines list --suite storybook
pxdiff baselines list --suite storybook --output json

Inspect baseline metadata for a suite ref. This does not change the baseline.

Terminal window
pxdiff baselines metadata --suite <suite> --ref <ref> [options]
FlagTypeDefaultDescription
--suitestringSuite name (required)
--refstringBaseline ref, such as main (required)
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff baselines metadata --suite storybook --ref main
pxdiff baselines metadata --suite storybook --ref main --output json

Show read-only billing balance, current period spend, and budget status for the authenticated project.

Terminal window
pxdiff billing [options]
FlagTypeDefaultDescription
--outputstringtextOutput format: text or json
--api-keystringAPI key
--api-urlstringAPI URL
--projectstringProject context for session auth (org/project)
Terminal window
pxdiff billing
pxdiff billing --output json

For pricing, deposits, and budget behavior, see the billing guide.


Fetch raw JSON from a read-only pxdiff API endpoint. This is a low-level inspection/debug interface for advanced users and coding agents who need endpoints not yet covered by first-class commands. Prefer the inspect commands above for common suites, diffs, captures, baselines, and billing reads.

Only GET requests are supported, and only for /api/v1/* JSON endpoints. This command reuses normal CLI authentication: project API keys work directly, and browser-login sessions work when the current directory is linked to a project or you pass --project. It returns raw API JSON rather than the stable JSON shape of the first-class inspect commands.

Terminal window
pxdiff api get <path> [options]
ArgumentDescription
pathAPI path under /api/v1/* (required)
FlagTypeDefaultDescription
--api-keystringAPI key
--api-urlstringhttps://pxdiff.comAPI base URL
--projectstringProject context for session auth (org/project)
Terminal window
# Inspect a diff payload
pxdiff api get /api/v1/diffs/diff_abc
# Inspect snapshot summary with session auth outside a linked repo
pxdiff api get /api/v1/suites/storybook/diffs/diff_abc/snapshots/summary --project myorg/my-app

Authenticate the CLI via your browser using GitHub OAuth.

Terminal window
pxdiff login [options]
FlagTypeDefaultDescription
--api-urlstringhttps://pxdiff.comAPI base URL
Terminal window
# Login to production
pxdiff login
# Login to a custom instance
pxdiff login --api-url http://localhost:3100

Clear stored credentials and invalidate the session.

Terminal window
pxdiff logout [options]
FlagTypeDefaultDescription
--api-urlstringhttps://pxdiff.comAPI base URL
Terminal window
pxdiff logout

Show current authentication status and linked project.

Terminal window
pxdiff whoami [options]
FlagTypeDefaultDescription
--api-urlstringhttps://pxdiff.comAPI base URL
Terminal window
pxdiff whoami

Link the current git repository to a pxdiff project. Used with session-based auth (pxdiff login).

Terminal window
pxdiff project set <org/project> [options]
ArgumentDescription
org/projectOrganization and project slug (required)
FlagTypeDefaultDescription
--api-urlstringhttps://pxdiff.comAPI base URL
Terminal window
pxdiff project set myorg/my-app

VariableDescriptionDefault
PXDIFF_API_KEYAPI authentication key (required for CI, optional when logged in)
PXDIFF_API_URLAPI base URLhttps://pxdiff.com
PXDIFF_PROJECTOverride project context (org/project)
PXDIFF_LOCALEnable local mode when set to truefalse
PXDIFF_SESSION_IDSession ID (set automatically by pxdiff)
PXDIFF_AUTO_APPROVEAuto-approve (set automatically by --auto-approve)
PXDIFF_BASELINE_REFBaseline ref (set automatically by --ref)
PXDIFF_BRANCHOverride git branch detection
PXDIFF_COMMITOverride git commit detection

When --branch and --commit are not provided, the CLI auto-detects them:

  1. Branch: GITHUB_HEAD_REFGITHUB_REF (strips refs/heads/) → CI_COMMIT_REF_NAMEgit rev-parse --abbrev-ref HEAD
  2. Commit: GitHub PR event payload → GITHUB_SHACI_COMMIT_SHAgit rev-parse HEAD
  3. Target refs (for pxdiff diff): Includes GITHUB_BASE_REF and PXDIFF_BASELINE_REF if set, then queries the API for all refs with baselines and uses git merge-base to find which are ancestors of HEAD. See Baseline Resolution for details.

This works automatically in GitHub Actions, GitLab CI, and local development.