Skip to content

Storybook

Visual regression testing for your Storybook components.

Terminal window
npm install -g @pxdiff/cli
npm run build-storybook

One-time setup — authenticate and link your project:

Terminal window
pxdiff login
pxdiff project set myorg/myproject

Capture and diff your Storybook:

Terminal window
pxdiff storybook ./storybook-static

Open the diff URL from the output to review changes.

Skip the build-storybook step entirely and capture against a Storybook dev server you’re already running. pxdiff launches a local Linux Docker container that runs the same Chromium image as cloud capture, so results are pixel-identical to CI.

Requires Docker. The CLI detects your installed Playwright version, pulls a matching runner image, and points Chromium at http://host.docker.internal:<port>. See the Docker guide for installation and troubleshooting.

Terminal window
# Terminal 1
npm run storybook # serves on http://localhost:6006
# Terminal 2
pxdiff storybook --port 6006

This flow is ideal for iterating on visual changes — edit a component, save, and re-run pxdiff storybook --port 6006 without rebuilding.

Notes:

  • Always local mode. Captures from --port are ephemeral and scoped to you — they do not update shared baselines or post GitHub check runs, even when CI is set. Use the static build path (pxdiff storybook ./storybook-static) in CI.
  • --only-changed is not supported with --port. Change detection relies on the Storybook module graph from a --stats-json build.

Create an API key for your project and set it as a repository secret.

.github/workflows/visual.yml
name: Visual Regression
on: pull_request
jobs:
visual:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build-storybook
- run: pxdiff storybook ./storybook-static
env:
PXDIFF_API_KEY: ${{ secrets.PXDIFF_API_KEY }}

For a simpler setup, use the pxdiff/storybook action which handles install, capture, diff, and check run posting in one step:

- name: Build Storybook
run: npm run build-storybook
- name: pxdiff
uses: pxdiff/storybook@v1
with:
api-key: ${{ secrets.PXDIFF_API_KEY }}
build-dir: ./storybook-static

When --only-changed is enabled, pxdiff uses Storybook’s module graph to determine which stories are affected by code changes and only captures those. Unchanged stories have their baselines carried forward automatically.

This requires building Storybook with --stats-json to produce preview-stats.json:

Terminal window
npm run build-storybook -- --stats-json
pxdiff storybook ./storybook-static --only-changed
  1. Fetches the baseline commit hash from pxdiff (the commit that last set baselines for this suite)
  2. Runs git diff between the baseline commit and HEAD to get changed files
  3. Parses preview-stats.json (the bundler’s module graph) and index.json (the story index)
  4. Traces changed files upward through the import graph to find which story files are affected
  5. Only captures affected stories; unchanged stories are skipped

Change detection falls back to capturing all stories when it can’t determine the impact:

  • No preview-stats.json in the build directory
  • First run (no baselines exist yet)
  • Baseline commit not in local git history (shallow clone — use fetch-depth: 0)
  • .storybook/ config files changed
  • package.json or lockfile changed
  • Changed files can’t be traced to any story
- name: Build Storybook
run: npm run build-storybook -- --stats-json
- name: pxdiff
uses: pxdiff/storybook@v1
with:
api-key: ${{ secrets.PXDIFF_API_KEY }}
build-dir: ./storybook-static
only-changed: true
auto-approve: ${{ github.ref == 'refs/heads/main' }}

Make sure your checkout step uses fetch-depth: 0 so the baseline commit is available in the git history:

- uses: actions/checkout@v4
with:
fetch-depth: 0

Filter to specific stories to speed up local iteration:

Terminal window
pxdiff storybook ./storybook-static --filter "Button*"

The --filter flag accepts glob patterns. Only matching stories are captured and diffed.

See the CLI reference for all pxdiff storybook options and Storybook parameters for per-story configuration.