All docs
Getting started2 min readUpdated

Storybook visual regression testing

Add visual regression testing to Storybook in minutes: install the uiverify CLI, build your stories, and get a screenshot diff check on every pull request.

If you already have Storybook, you already have your capture targets: every story is a state worth screenshotting. UI Verify renders each one, captures it, and diffs it against the baseline. Here is the whole setup.

1. Get a project API key

Sign up at uiverify.ai, create a project, and copy its API key. Store it in your CI as a secret named UIVERIFY_API_KEY.

2. Build your Storybook

bash
npm run build-storybook   # outputs ./storybook-static

3. Upload it

Run this locally to establish your first baselines. Pass the API key inline (or export it first) - the CLI reads it from the environment.

bash
UIVERIFY_API_KEY=your_key npx -y uiverify@latest upload --static-dir ./storybook-static

The first run establishes your baselines. Every run after it diffs against them and reports what moved.

4. Install the GitHub App

Install the GitHub App from your project settings and point it at your repo. This is what lets UI Verify post a check and a comment on each pull request. Uploads still work without it, but nothing shows up on GitHub, so do this before you wire CI up.

5. Wire it into CI

.github/workflows/visual.yml
name: UI Verify
on: pull_request

jobs:
  visual:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0   # full history so the baseline can be resolved
      - run: npm ci && npm run build-storybook
      - run: npx -y uiverify@latest upload --static-dir ./storybook-static
        env:
          UIVERIFY_API_KEY: ${{ secrets.UIVERIFY_API_KEY }}
fetch-depth: 0 matters: the default shallow checkout hides your branch history, and UI Verify needs it to resolve the right baseline. Without it you get phantom diffs.

6. Review changes on the pull request

UI Verify posts a check and a comment on the PR. Changed stories go to a review queue where you accept or reject each one; accepting promotes the new screenshot to the baseline for that branch. See how the review model works.

Render only what changed

On a large Storybook, add --only-changed to render just the stories your PR affects and carry the rest forward. It needs Storybook's dependency graph, which Storybook only writes when you build with --stats-json (npm run build-storybook -- --stats-json). It is the single biggest lever on build time and cost - see Skip unchanged stories.

Frequently asked questions

Do I need to write new tests?

No. Your existing stories are the tests. If a component has no story yet, add one story that renders it - and prefer a dense gallery story over one story per variant.

Why does a story come back changed when nothing changed?

That is a flaky diff, and it is almost always run-to-run variation the screenshot faithfully captured - a clock, an animation, live data. See Fix flaky visual tests.

Visual testing for agents

UI Verify captures your UI on every pull request and an AI judge tells an intended change from a real regression. See how it works.

Get started