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.

Upload a Storybook build, discover stories, and capture screenshots in one step.

Terminal window
pxdiff storybook <dir> [options]
ArgumentDescription
dirPath to the static Storybook build directory (required)
FlagTypeDefaultDescription
--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)
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseRun in local mode (also set via PXDIFF_LOCAL=true)
--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)
--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)

Workflow:

  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
Terminal window
# Basic usage
pxdiff storybook ./storybook-static
# Filter to specific stories
pxdiff storybook ./storybook-static --filter "Button*" --suite ui
# JSON output for CI parsing
pxdiff storybook ./storybook-static --output json

Upload a Ladle build, discover stories, and capture screenshots in one step.

Terminal window
pxdiff ladle <dir> [options]
ArgumentDescription
dirPath to the static Ladle build directory (required)
FlagTypeDefaultDescription
--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)
--ephemeralbooleanfalseNo branch/commit tracking
--localbooleanfalseRun in local mode (also set via PXDIFF_LOCAL=true)
--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)

Workflow:

  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
Terminal window
# Basic usage
pxdiff ladle ./build
# 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 CI session. Creates a GitHub check run and manages the session lifecycle.

Terminal window
pxdiff run [options] -- <command...>
FlagTypeDefaultDescription
--auto-approvebooleanfalseAuto-approve changed snapshots
--api-keystringAPI key
--api-urlstringAPI URL
--dockerstring/booleanRun inside Docker for consistent rendering. Optionally specify a custom image.

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.

Terminal window
# Wrap a Playwright test run
pxdiff run -- npx playwright test
# Wrap all tests (multi-suite — each plugin declares its own suite)
pxdiff run -- npm test
# Run inside Docker for consistent cross-platform rendering
pxdiff run --docker -- npx playwright 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 posts GitHub check runs

Run a command in local development mode with pxdiff environment configured.

Terminal window
pxdiff local [options] -- <command...>
FlagTypeDefaultDescription
--auto-approvebooleanfalseSet PXDIFF_AUTO_APPROVE=true
--refstringBaseline ref (sets PXDIFF_BASELINE_REF)
--dockerstring/booleanRun inside Docker for consistent rendering. Optionally specify a custom image.
Terminal window
# Run Playwright tests locally with pxdiff
pxdiff local -- npx playwright test
# Auto-approve against main
pxdiff local --auto-approve --ref main -- npm test
# Run inside Docker for consistent cross-platform rendering
pxdiff local --docker -- npx vitest run

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

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 run and local commands)
PXDIFF_AUTO_APPROVEAuto-approve (set automatically by run --auto-approve and local --auto-approve)
PXDIFF_BASELINE_REFBaseline ref (set automatically by local --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. Baseline ref: GITHUB_BASE_REFPXDIFF_BASELINE_REF

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