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.
Set it up with your coding agent
Paste this into Claude Code, Cursor, or any coding agent and it wires up UI Verify from these docs.
Set up UI Verify visual regression testing for my Storybook project. Follow https://uiverify.ai/docs/quickstart-storybook to install the packages and add the config. https://uiverify.ai/llms-full.txt has the same docs as one plain-text reference if you want to read them without fetching each page. Then run one build and upload it right now, locally - no CI or GitHub App needed for this - so my first build lands in the dashboard and we can confirm the setup works before wiring anything else. Use the upload command from the quickstart. Open the build page it prints in my browser so I can see the captured stories. Ask me for my UIVERIFY_API_KEY when you need it for the upload. Install the UI Verify skills for this project - the making-ui-changes playbook, the economical-visual-tests, triage, and check-visual-changes playbooks, plus the deterministic-capture guide for this framework - so you can change UI safely, author cheap stable stories, preview an edit's visual impact before pushing, and review builds yourself: npx skills add uiverify/uiverify \ --skill making-ui-changes \ --skill economical-visual-tests \ --skill triage-visual-changes \ --skill check-visual-changes \ --skill storybook-visual-testing Then add a short rule to my AGENTS.md and CLAUDE.md so you read the making-ui-changes skill before any UI change from now on: `Before changing any component, page, or styles, read the making-ui-changes skill and follow it - reuse before you create, add/update the story or capture in the same change, check the blast radius on shared components, and prove the change with a visual test.` After installing, restart this session (or reload the window) so the new skills load - you will not have them until I do. Once that first build is in and looks right, wire the GitHub Actions workflow from the quickstart so every push is checked (add UIVERIFY_API_KEY as a repository secret), and remind me to install the UI Verify GitHub App from my setup page so the check and PR comment post - that's the one step only I can do, and it isn't needed for the first upload.
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
npm run build-storybook # outputs ./storybook-static3. 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.
UIVERIFY_API_KEY=your_key npx -y uiverify@1.4.0 upload --static-dir ./storybook-staticYour first run captures every story as new and flags them for review - accept them to set your baselines. After that, each run diffs against those baselines and reports what moved.
4. Catch a change locally
You do not need CI or a pull request to see a diff. Change something visible in a story - a color, a label - then rebuild Storybook and re-run the exact same upload on the same commit. UI Verify diffs the new build against your first one and flags what moved, so you see the review flow before wiring anything up.
npm run build-storybook
UIVERIFY_API_KEY=your_key npx -y uiverify@1.4.0 upload --static-dir ./storybook-staticOpen the build page it prints: the changed story is waiting in the review queue, where you accept or reject it. Accepting promotes the new screenshot to the baseline for that branch.
5. Wire it into CI
name: UI Verify
on: pull_request
jobs:
visual:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # full history so the baseline can be resolved
- run: npm ci && npm run build-storybook
- run: npx -y uiverify@1.4.0 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.
7. Install the visual-testing skills
Give your coding agent the visual-testing playbooks so it can do the work in your repo: triage a build's changes, write economical visual tests, check an edit's visual impact before pushing, and keep captures deterministic. This installs just these skills, not the whole bundle. Restart the agent session afterward so they load.
npx skills add uiverify/uiverify \
--skill making-ui-changes \
--skill economical-visual-tests \
--skill triage-visual-changes \
--skill check-visual-changes \
--skill storybook-visual-testing8. Review changes from your coding agent
Connect the UI Verify MCP and your agent can pull a build's changes into the conversation, look at each diff, read the AI judge's verdict, and accept the intended ones. Your project setup page has this command with the key already filled in; the header is your UIVERIFY_API_KEY. See Triage visual changes from your coding agent.
claude mcp add --scope project --transport http uiverify https://uiverify.ai/api/mcp \
--header 'Authorization: Bearer ${UIVERIFY_API_KEY}'Project scope writes it to your committed .mcp.json, so the whole team gets it. The key is referenced as the UIVERIFY_API_KEY env var (single-quoted so your shell does not expand it at add time), not baked in, so the committed file never holds the secret: each teammate sets UIVERIFY_API_KEY in their environment and Claude Code expands it at runtime.
9. Install the GitHub App
Install the UI Verify GitHub App from your project's setup page and point it at your repo, so it can post a check and a comment on each pull request. This is the one step your coding agent cannot do for you. It does not block getting started: your first upload and baselines work without it, so add it when you want the results to show up on GitHub.
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.
Skip a story
Every story is snapshotted by default. To exclude one, set disableSnapshot in its parameters. UI Verify reads it under parameters.uiVerify, and also under parameters.chromatic, so an existing Chromatic config carries over unchanged. Set it on a single story, or on the component's meta to skip the whole file. A story with a play function runs its interaction testing steps first, and the snapshot captures the settled result.
export const Playground: Story = {
// rendered in Storybook, never screenshotted or billed
parameters: { uiVerify: { disableSnapshot: true } },
};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.
Set up visual testing
From no visual tests to a green check on every pull request.
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