Skip to content

Ladle

Visual regression testing for your Ladle components.

Terminal window
npm install -g @pxdiff/cli
npx ladle build

One-time setup — authenticate and link your project:

Terminal window
pxdiff login
pxdiff project set myorg/myproject

Capture and diff your Ladle build:

Terminal window
pxdiff ladle ./build

Open the diff URL from the output to review changes.

Skip the ladle build step entirely and capture against a Ladle 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
npx ladle serve # serves on http://localhost:61000
# Terminal 2
pxdiff ladle --port 61000

This flow is ideal for iterating on visual changes — edit a story, save, and re-run pxdiff ladle --port 61000 without rebuilding.

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 ladle ./build) in CI.

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: npx ladle build
- run: pxdiff ladle ./build
env:
PXDIFF_API_KEY: ${{ secrets.PXDIFF_API_KEY }}

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

- name: Build Ladle
run: npx ladle build
- name: pxdiff
uses: pxdiff/ladle@v0
with:
api-key: ${{ secrets.PXDIFF_API_KEY }}
build-dir: ./build

Filter to specific stories to speed up local iteration:

Terminal window
pxdiff ladle ./build --filter "Badge*"

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

Control capture behavior per-story using the meta.pxdiff field:

export const MyStory = () => <Component />;
MyStory.meta = {
pxdiff: {
delay: 500,
selector: ".wrapper",
cropToViewport: true,
ignoreSelectors: [".timestamp"],
disable: false,
},
};

See the CLI reference for all pxdiff ladle options.