Local development
When you're iterating on a component, it's often useful to run Happo from your
machine before opening a PR. Combined with the
--only flag, you can scope the run down to just the
components you care about and get a link to the report in the browser.
This works for both the Storybook integration and custom integrations.
The job URL
When Happo finishes uploading, it logs two URLs:
[HAPPO] Async report URL: https://happo.io/a/8/async-reports/2387412
[HAPPO] Async comparison URL: https://happo.io/a/8/jobs/2233741
The second one — the async comparison URL — is the one to open. It takes you to a job page that shows the diff against the baseline as the screenshots come in.
The report you land on will contain all components and snapshots from
your project — the ones included via --only are freshly rendered, and the
rest are carried over from the baseline report so the comparison is complete.
You're only charged quota for the snapshots that were actually generated.
Running with --only
The --only flag accepts a JSON array of components or story files to render
exclusively. See the CLI reference for the full entry
format.
npm run happo --only '[{"component":"Card"}]'
Typing the JSON by hand gets old quickly, so a small wrapper script is usually nicer to work with. Two patterns we've found useful are below.
Pattern 1: pass the file as an argument
The simplest setup is a script that takes a single file path on the command
line and forwards it to Happo as --only. The script needs to:
- Read the file (or component) name from
process.argv. - Build the
--onlyJSON payload — for example[{ storyFile: './src/stories/Button.stories.js' }]for Storybook, or[{ component: 'Button' }]for custom integrations. - Spawn
happo --only <json>with inherited stdio so the[HAPPO] Async comparison URLline shows up in your terminal.
Run it like this:
node scripts/happo-only.mjs src/stories/Button.stories.js
When the run finishes, click the Async comparison URL in the output to see the report.
Pattern 2: detect changed files automatically
To run Happo against every story or component affected by your in-flight
changes, you can combine git diff with a dependency-graph tool such as
jest-haste-map
or dependency-cruiser.
The idea: collect the files you've changed since the base branch, then walk
the import graph to find the story/example files that (transitively) depend
on any of them.
The script needs to:
- Collect changed files —
git diff --name-only origin/main...HEADfor committed work plusgit diff --name-onlyfor uncommitted edits. - Build a dependency graph for the project.
jest-haste-mapanddependency-cruiserare both good options; any tool that can answer "given file X, what does it import?" works. - Find the story or example files that depend on a changed file. For
Storybook, filter to
*.stories.{js,ts,jsx,tsx}; for custom integrations, filter to whatever pattern your examples live under. - Map each match to an
--onlyentry —{ storyFile: './path/to/foo.stories.js' }for Storybook,{ component: 'Foo' }for custom integrations. - Spawn
happo --only <json>with inherited stdio. Always log the JSON you computed — if a run looks wrong, that log is the fastest way to see what was included.
Run it from the project root with no arguments:
node scripts/happo-changed.mjs
Happo runs a partial build — only the components your change touches are freshly rendered, and the report still includes everything else carried over from the baseline so the comparison is complete. The CLI prints the Async comparison URL when the run is done.
Tips
- Log the
--onlyvalue your script computes. It's the quickest way to diagnose a run that included more or fewer components than you expected. - If your script can't find any affected stories, exit early instead of
running a full Happo build —
--onlywith an empty array is not the same as "nothing changed."