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 --local
pxdiff diff

Open the diff URL from the output to review changes.

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
pxdiff diff
env:
PXDIFF_API_KEY: ${{ secrets.PXDIFF_API_KEY }}

For a simpler setup, use the pxdiff/storybook action which handles install, capture, and diff 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 --local --filter "Button*"
pxdiff diff

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.