How to Set Up Happo Visual Regression Testing with Storybook
Set up Happo with Storybook, run visual checks locally and in CI, and manage baselines, partial runs, and flaky stories.
To set up Happo visual regression testing with Storybook, install the happo development dependency, configure the Storybook integration in happo.config.ts, add a CLI script, and run it. Then add Happo to CI. If pull requests use partial runs, keep full reports on the default branch so Happo has baseline screenshots to compare against.
This guide uses Happo’s current Storybook integration, exposed by the happo package. A working Storybook is a prerequisite. Before adding automation, make sure its stories cover the component states you want to review: default, loading, error, expanded, and other states that matter to your product.
1. Install Happo
Install happo as a development dependency using your package manager:
# npm
npm install --save-dev happo
# pnpm
pnpm add --save-dev happo
# Yarn
yarn add --dev happo
Use one command, matching the package manager your repository uses. The current integration is part of happo; older setup material may refer to a separate happo-plugin-storybook package.
2. Configure the Storybook integration
Create happo.config.ts at the repository root:
import { defineConfig } from 'happo';
export default defineConfig({
integration: {
type: 'storybook',
configDir: '.storybook',
},
});
The .storybook directory is the default Storybook configuration directory. Set configDir if yours is elsewhere. Add other path options only when your project needs them:
outputDir: where Happo should find or place the built Storybook output. If you use an existing build, set this to that build’s location.staticDir: the static asset directory when your Storybook setup needs one.usePrebuiltPackage: use an existing prebuilt Storybook package when your build process provides one.
Keep paths aligned with the build that CI actually produces. A local configuration that points to one output directory and a CI build that writes to another can make the integration appear to have no stories or assets.
3. Add a script and run Happo
Add the CLI command to package.json:
{
"scripts": {
"happo": "happo"
}
}
Run the capture locally:
npm run happo
Use the equivalent package-manager command if needed, such as pnpm happo or yarn happo. Happo’s CLI places its client runtime in the Storybook package it builds. Current setup does not require you to hand-add a runtime registration import just to get screenshots.
4. Add optional Storybook helpers only when useful
The core capture setup does not require a manual registration import. If you need Storybook-side helpers such as theme switching or forced screenshots, the current documentation supports importing happo/storybook/register from .storybook/preview.js (or the equivalent preview file in your project):
import 'happo/storybook/register';
The Happo panel is also optional. It can help inspect parameters and test hooks while developing stories. Treat both the registration helpers and panel as development aids, not prerequisites for the CLI workflow. If adding a decorator under a renderer other than React, check Happo’s compatibility note: versions before v6.19.1 have a documented compatibility issue.
5. Make stories useful for regression checks
A screenshot can only catch a visual change in a state that is represented by a story and selected for capture. Add stories for the variants your team wants to protect, including important themes and interaction states. You can exclude an unsuitable story by setting its happo parameter to false.
For multiple themes, use theme parameters and the documented theme-switcher helper so the same component can be captured under each relevant theme. If one story changes browser state in a way that leaks into the next story, use navigatePerStory to force a fresh page load per story. This can improve isolation but makes the run slower.
For asynchronous content, prefer a condition such as waitFor or waitForContent where appropriate. A fixed delay is a last resort: it adds time and can hide an unresolved readiness condition. The documented default render timeout is two seconds; increase it only for stories that genuinely need longer, such as a longer interaction flow.
6. Run Happo in CI and maintain baselines
Add the Happo CLI to your CI workflow after dependencies are installed and the Storybook build can run. The exact workflow syntax depends on your CI provider and repository; the essential behavior is:
- On pull requests, run the selected visual checks and compare them with the appropriate baseline.
- On pushes to the main or default branch, produce full reports so those screenshots remain available as baselines.
- When changing the selection logic or Storybook build, verify that the default-branch run still captures the complete intended story set.
Partial pull-request runs depend on a recent baseline. If the baseline is missing or its files cannot be resolved, Happo documents fallback behavior that can trigger a full run. Full reports on the default branch make the comparison more predictable and give the team a complete reference point.
Visual comparisons are useful for presentation changes such as layout, spacing, styling, and typography. They complement functional tests, which exercise behavior. A screenshot suite does not establish that interactions work correctly. Happo describes its browser, responsive, CI review, and accessibility capabilities on its product pages; verify the targets available for your selected plan and configuration.
7. Control run size with filters
A full run is the simplest starting point and avoids errors in custom change-to-story analysis. For a larger suite, Happo supports --only to include selected stories and --skip to exclude selected stories. Excluded stories can be carried into the comparison from a recent baseline; only freshly rendered screenshots count against quota.
For a custom --only filter based on changed files, a robust approach is to build a module dependency graph and select stories that transitively import a changed file. Treat changes you cannot analyze conservatively: run the full suite. Static analysis can miss dynamic loading patterns such as require.context and import.meta.glob. Audit for these patterns or keep affected areas in full runs. Changes to Storybook configuration, package metadata, and lockfiles can affect many stories; Happo’s own setup treats such changes as global.
Happo founder and CEO Henric Persson reported that Happo’s own Storybook build reduced snapshot volume by 40% after adopting --only. That is a vendor-reported internal result, not a guaranteed or independently measured saving for another project. See Happo’s explanation of partial runs and coverage.
8. Cost, speed, and reliability considerations
- Cost: Snapshot volume is the key consideration when sizing a suite. Filters can reduce newly rendered screenshots, but only when the selection is safe and the baseline is available. Check Happo’s current pricing for the service’s plan terms and snapshot-based pricing.
- Speed: Partial selection can avoid rendering unchanged stories. A fresh page load per story improves isolation at the expense of runtime. Avoid unnecessary fixed waits.
- Reliability: Stable stories, explicit readiness conditions, complete default-branch baselines, and conservative behavior for unknown changes reduce avoidable gaps and flakiness. Do not silently treat a failed dependency analysis as “no stories changed.”
- Coverage: A filter that is too narrow can miss a visual regression in a shared component. Include dependent stories and globally affected stories, or use a full run when uncertain.
9. Troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| No screenshots or no stories found | The integration is pointed at the wrong Storybook configuration or output directory, or the build did not include the expected stories. | Confirm configDir, align outputDir with the actual build, and verify that the Storybook build completes with the expected stories. |
| Static assets are missing | The static directory is not available to the build Happo is capturing. | Check the Storybook static asset configuration and set staticDir if your project requires it. |
| A pull request unexpectedly runs a full suite | A recent baseline is unavailable or Happo cannot resolve baseline files; documented fallback behavior may run a full capture. | Ensure the default branch produces full reports and that the baseline is accessible to the PR run. |
| A partial run misses a changed component | The file-to-story filter did not include transitive dependents or missed dynamic imports. | Expand dependency analysis, account for require.context and import.meta.glob, or use a full run for uncertain changes. |
| Stories appear to affect each other | Page or application state is leaking between captures. | Try navigatePerStory for a fresh page load, then account for the slower run. |
| Async content is missing or inconsistent | The capture starts before the story is ready, or a fixed delay is too short or variable. | Use a suitable waitFor or waitForContent condition. Increase the render timeout above the documented two-second default only when the story needs it. |
| Decorator or panel compatibility issue | An older Happo version or non-React renderer may hit the documented compatibility limitation. | Use current Happo documentation and check the note for versions before v6.19.1; keep the panel and decorator optional. |
Or skip the browser setup
For website screenshots, ScreenshotNeo provides a screenshot API and MCP server. It does not replace Happo’s Storybook component regression workflow: it captures a URL. It can help when you need a clean screenshot of a deployed page without managing a browser capture service yourself.
One GET request returns an image or PDF. The following example saves a WebP response:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
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}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
Do I need to add a Happo registration import to preview.js?
No. The current CLI integration places its runtime in the Storybook package it builds. Add the optional registration module only if you need its Storybook helpers.
Can Happo replace interaction tests?
No. Screenshot comparisons show rendered appearance; interaction tests are needed to exercise behavior.
Should I start with a partial run?
Start with a full run to establish coverage and baselines. Add filtering after the suite and its dependencies are understood.
Which CI provider should I use?
The setup is not tied to a provider in this guide. Add the CLI to the workflow your repository already uses, ensuring default-branch full reports and pull-request comparisons.
Sources
- Happo Storybook documentation — setup, options, filtering, parameters, and troubleshooting.
- Integrating Storybook with Happo — prerequisites and integration overview.
- How to grow your Happo coverage without losing control of your bill — partial-run behavior, cost discussion, vendor-reported result, and analysis caveats.
- Happo Storybook screenshot testing — vendor-described service capabilities.
- Happo pricing — current plan and pricing terms.


