Visual Delta

Local-first visual regression testing for Storybook with Playwright baselines, pixel diffs, and in-Storybook review.

View on GithubNew to Storybook?Get started

Visual Delta for Storybook

npm release and provenance npm version Storybook

Visual Delta is a local-first visual regression testing addon for Storybook. It compares stories with committed Playwright screenshots and adds baseline review, overlays, diffs, and visual test controls to Storybook.

Requirements

  • A Storybook project using Vite
  • React, which renders the addon panel
  • Playwright for browser capture
  • Docker for the default authoritative Linux ARM64 capture runner

Visual Delta supports Chromium, Firefox, and WebKit. New projects enable Chromium only.

Install

From your Storybook project, install and register the addon:

npx storybook add @lapismd/storybook-addon-visual-delta
pnpm add -D playwright react
pnpm exec playwright install chromium
pnpm exec visual-delta init

visual-delta init creates the Playwright suite, Playwright configuration, snapshot directory, and package scripts. It preserves existing files unless you pass --force.

The generated files are:

playwright.config.ts
tests/visual/storybook.spec.ts
tests/visual/storybook.spec.ts-snapshots/

It also adds build-storybook, test:visual, test:visual:affected, and visual-delta scripts when they do not already exist.

Check an installation

Run the fast, read-only doctor after setup or an upgrade:

pnpm exec visual-delta doctor

It validates Storybook registration, the portable Playwright suite, package dependencies and scripts, resolved capture settings, snapshot ownership, and Visual Delta artifact/cache placement. The default check does not build Storybook, start Docker, launch a browser, or write files.

Use the opt-in checks and repairs when needed:

pnpm exec visual-delta doctor --runner
pnpm exec visual-delta doctor --build
pnpm exec visual-delta doctor --strict --json
pnpm exec visual-delta doctor --fix

--runner performs the existing Docker or custom-runner probe. --build refreshes static Storybook before authoritative orphan analysis. --fix only moves verified v4 actual/diff/result evidence into .visual-delta/artifacts/, quarantines obsolete derived files under .visual-delta/cache/doctor-quarantine/, and migrates the legacy change-set cache. It never modifies committed baseline PNGs, story sources, or project configuration, and it never overwrites a destination.

Register the addon manually

If the Storybook CLI did not update your configuration, add the package to the existing addons array in .storybook/main.ts:

export default {
  addons: ["@lapismd/storybook-addon-visual-delta"],
};

If you do not want to use visual-delta init, create the suite and Playwright configuration yourself.

// tests/visual/storybook.spec.ts
import {
  defineVisualSuite,
} from "@lapismd/storybook-addon-visual-delta/playwright";

defineVisualSuite();
// playwright.config.ts
import {
  defineVisualPlaywrightConfig,
} from "@lapismd/storybook-addon-visual-delta/playwright";

export default defineVisualPlaywrightConfig();

Create a baseline

Start Storybook and open a story:

pnpm storybook

Open the Visual Delta panel, select the browser, and choose Create visual. Review the captured PNG before committing it to your repository.

The default snapshot directory is tests/visual/storybook.spec.ts-snapshots. Baseline names contain the story and browser, for example components-button--primary-chromium.png.

Run visual tests

Check the full capture environment before the first authoritative run (the legacy runner-only spelling remains supported):

pnpm exec visual-delta doctor --runner

Run every eligible story:

pnpm test:visual

Run only stories affected by local changes:

pnpm test:visual:affected

Missing baselines and visual mismatches are warnings by default. Use strict mode when they should fail CI:

pnpm exec visual-delta test --all --failure-mode strict

Compare one exact story with the same runner-backed suite used by Diff Browser:

pnpm exec visual-delta test --story-id examples-card--default --browser chromium

Compare-only commands never create or update baselines. They write mirrored .actual.png, .diff.png, and .result.json evidence to .visual-delta/artifacts/; affected planning state lives in .visual-delta/cache/, including UI change-set history at .visual-delta/cache/change-sets/ and verified canonical Storybook builds at .visual-delta/cache/canonical-build/. Both roots are ignored by default, but projects may cache or commit them. Add --fresh to bypass a reusable actual once while retaining the canonical build cache; add --rebuild to force a new canonical Storybook build. Affected selection is enabled conservatively when the addon option is omitted; set affectedTests: false to opt out.

Configure browsers and comparison defaults

Add .visual-delta/config.json when the built-in defaults are not suitable:

{
  "browsers": ["chromium", "firefox", "webkit"],
  "captureWorkspaceIgnore": [".nx/cache"],
  "workflow": {
    "visualTestFailureMode": "strict",
    "reuseActualComparisons": true
  }
}

Install local browser binaries only when developing the host-local diagnostic capture path or invoking Playwright directly:

pnpm exec playwright install chromium firefox webkit

captureWorkspaceIgnore accepts root-relative derived-cache directories that the clean runner should omit. The runner already excludes common caches such as .turbo; use this setting for tool-specific caches without waiting for another package release.

The built-in comparison allows up to 0.063% differing pixels and uses a 0.063 per-pixel color threshold. Project and story settings can override these values.

The default runner executes authoritative comparisons in the pinned Linux ARM64 capture profile. Diff Browser, the Testing Module, and command-line tests all invoke the same packaged Playwright worker through that runner. Projects that cannot use Docker can provide .visual-delta/runner.mjs to transport the same capture job through another environment.

Further documentation

License

MIT

Made by
  • stevejuma
    stevejuma
Work with
    Angular
    Ember
    HTML
    Preact
    React
    React native
    Svelte
    Vue
    Web Components
Tags