Storybook Visual Testing: How to Catch UI Regressions
Catch unintended UI changes by comparing Storybook stories with approved visual baselines. Set up local reviews and CI checks that make changes easier to investigate.
Storybook visual testing catches UI regressions by capturing the rendered appearance of stories and comparing each result with an approved baseline. The comparison shows what changed; a reviewer decides whether the change is intentional. Set up representative stories, establish a baseline you have inspected, and run comparisons during development and in CI before merge.
What Storybook visual testing checks
A story renders a component in a particular state, with specified content and inputs. Visual testing captures that rendered result and compares it with a known-good reference. Differences can reveal changes in layout, color, size, spacing, typography, or contrast.
A visual diff is a review signal, not a verdict. If a change is intended, approve the new baseline. If it is accidental, fix the component or its styles and rerun the check.
| Test type | What it compares | Useful for |
|---|---|---|
| Visual test | Rendered pixels or appearance | Finding visible changes to a story |
| Markup snapshot | Serialized HTML or other output | Finding changes in rendered markup |
| Interaction or component test | Behavior and assertions | Checking that controls and flows work |
These methods complement one another. A markup change may not alter what a user sees, while a visual test does not establish that a button behaves correctly. Use behavior tests when behavior matters too.
Prepare stories that protect the states you care about
Visual checks only compare the stories you render. As a practical consequence, a component state without a representative story is outside the comparison. Include the variants and conditions your team wants to review, such as:
- Default, hover, focus, disabled, loading, and error states where relevant.
- Short and long content, empty states, and content that wraps or overflows.
- Light and dark themes, supported locales, and important viewport sizes.
- Representative data, including boundary values that affect layout.
Keep stories deterministic. Avoid relying on the current time, random values, live API responses, or other changing inputs unless the test setup fixes them. Otherwise, the baseline can change for reasons unrelated to the code under review.
Set up Storybook visual tests with Chromatic
Storybook documents @chromatic-com/storybook as its official addon for the hosted Chromatic visual-testing service. The Storybook v8 guide specifies Storybook 7.6 or later. Because prerequisites and commands can vary by Storybook release, check the official guide for your project’s version before installing.
- Open the visual testing guide for your Storybook release and confirm its prerequisites.
- From the project root, run the documented setup command:
npx storybook@latest add @chromatic-com/storybook - Follow the setup prompts to sign in or select the Chromatic project connected to your Storybook.
- Inspect the stories in the first build, then establish the initial baseline only after confirming the rendered UI is the state you intend to protect.
The first build creates reference snapshots. Later builds render the stories again and compare the results with approved references. See the Storybook v8 visual testing guide and select documentation appropriate to your installed release.
Review diffs and update baselines safely
- Run the visual check after a UI change, locally during development or through the connected service.
- Open the reported changed stories and inspect the highlighted visual differences in context.
- Decide whether each difference is expected. Check nearby states and themes when a shared component or token changed.
- For an intended change, approve the updated baseline through the service’s review flow.
- For an unintended change, fix the implementation, rerun the check, and review the new result.
Do not approve a batch of changes without reviewing them. A broad baseline update can conceal an unintended change alongside a planned redesign. Keep the reason for a deliberate baseline update in the pull request or review notes so later reviewers understand it.
Run visual checks in CI before merge
Storybook recommends running visual checks while developing and integrating them into CI. Configure the project token as a secret or environment variable using the current Chromatic instructions. Do not commit a token to the repository or print it in build logs.
- Connect the repository’s CI workflow to the Chromatic project using its current CI setup guide.
- Store the project token in the CI provider’s secret store and expose it only to the relevant job.
- Run the visual build for the branch or pull request so reviewers can inspect changes before merge.
- Make the check a merge requirement if that fits your team’s review policy.
- Confirm the check reports status back to the pull request and that a failed or pending build cannot be mistaken for an approved result.
Exact workflow YAML and token variable names depend on the CI provider and the current service integration. Use the provider-specific instructions rather than copying a guessed configuration.
Choose the right testing combination
Storybook visual tests focus on appearance. Combine them with interaction or component tests for behavior such as keyboard operation, validation, and state transitions. Storybook’s general-purpose Test Runner has a separate role: it runs story-based tests in a browser and is extensible. The current integration listing says official support for the standalone Test Runner has ended and points Vite-based projects toward the Vitest integration. Check the documentation for your Storybook version before choosing or migrating a runner.
The Test Runner documentation also notes that limiting workers can help when many stories or low-memory CI cause timeouts. That advice concerns the general-purpose runner; do not assume it is a setting for every hosted visual build.
Reliability, performance, and cost considerations
- Baseline quality: Inspect the initial UI before treating it as the reference. A mistaken baseline makes later comparisons less useful.
- Determinism: Fix time, data, and other variable inputs in stories where they affect rendering. Reduce animation or asynchronous changes when they make the captured state unstable.
- Coverage: Add stories for meaningful component states. A missing state cannot produce a visual diff.
- CI time and resources: The number of stories and the selected service or runner affect the amount of work. The supplied documentation does not establish a general runtime benchmark; measure the workflow in your own project.
- Review effort: Group related changes and explain intentional visual updates so reviewers can distinguish planned changes from surprises.
- Service terms: Check current vendor pricing, usage limits, browser coverage, and supported versions before adopting a hosted service. Those terms can change, and no pricing comparison is asserted here.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Setup command fails or addon is incompatible | Storybook release or project setup does not match the guide’s prerequisites. | Check the version-specific Storybook documentation and confirm the supported version before retrying. |
| Many stories show unexpected diffs | A shared style, font, theme, viewport, or global decorator changed, or the environment differs from the baseline. | Inspect shared configuration and compare the affected stories together. Approve only changes that are intended. |
| A story changes between runs without a code change | Time, random data, remote responses, animation, or asynchronous content is not stable. | Use fixed story inputs and deterministic fixtures; wait for the intended state before capture. |
| A state never appears in the results | There is no story that renders that state. | Add a representative story and include it in the visual workflow. |
| CI cannot authenticate | The project token is missing, invalid, scoped incorrectly, or unavailable to the job. | Check the secret name and job configuration against the current CI guide. Rotate a token if it was exposed in logs. |
| General-purpose test runner times out in CI | Many stories or limited memory can overwhelm the runner. | Follow the runner documentation’s worker guidance, review CI resources, and confirm whether the project should use the maintained integration for its framework. |
| Reviewers are unsure whether to accept a baseline | The intended design change and the observed difference are not explained. | Describe the planned UI change in the pull request, inspect the changed stories, and approve only the matching updates. |
Or skip the browser setup
If you need a screenshot of a live page rather than repeatable Storybook story baselines, ScreenshotNeo provides a website screenshot API and MCP server. It does not replace story-based visual regression review: it captures a URL on request.
For the full API options, see the ScreenshotNeo documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie and consent banners are accepted and removed before capture; newsletter popups and chat widgets are removed too. Each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and billing status.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for Claude, Cursor, and other MCP clients. - The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan.
Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.
FAQ
Can visual testing tell whether a UI change is correct?
No. It reveals a difference; a reviewer decides whether the change is intentional and correct.
Does a visual baseline test component behavior?
No. Pair appearance comparisons with interaction or component tests for behavior.
Should every story be included?
Include stories for the states your team wants to protect. A rendered story is the unit being compared.
Is the standalone Storybook Test Runner the same as Chromatic visual testing?
No. They serve distinct roles. Check current Storybook integration guidance for your release and framework.


