How to Configure Loki for Storybook Visual Regression Testing
Set up Loki to capture Storybook baselines, compare visual changes, and run repeatable checks in CI. Includes configuration, troubleshooting, and runnable examples.
Loki runs visual regression checks by capturing rendered Storybook stories and comparing them with reference screenshots. Install Loki as a development dependency, initialize its configuration, start Storybook, capture and commit the first references, then run loki test after changes. In CI, test a built Storybook and require references so missing baselines fail instead of being created silently.
This guide uses Yarn in commands; equivalent npm commands are included where useful. Loki’s documented setup lists Node.js 16 or later. Docker is optional for its Chrome Docker target, and GraphicsMagick is optional for the gm diff engine. Check the installation guidance for the Loki version you adopt, since prerequisites and supported targets can change. See the Loki README and getting started guide.
1. Install and initialize Loki
From the project root, add Loki as a development dependency and run its initializer:
yarn add loki --dev
yarn loki init
With npm:
npm install --save-dev loki
npx loki init
The initializer detects the project and writes a default configuration. Review the generated configuration rather than assuming its browser target, paths, or other defaults suit your project. Loki’s available targets include local, Docker, AWS Lambda, iOS simulator, and Android emulator; for typical web projects, its README recommends Chrome in Docker. Confirm the selected target remains supported by the Loki version you install.
2. Start Storybook and capture the first references
Loki does not start Storybook for you. Start the server yourself, then run the baseline capture in another terminal. For example, with a project script named storybook:
# Terminal 1
yarn storybook
# Terminal 2
yarn loki update
Keep the server running while Loki captures stories. Review the output and commit the reference screenshots with the code they describe. If the image collection is large, Loki’s documentation mentions Git LFS as an option.
3. Run comparisons and review changes
After changing components or styles, capture current screenshots and compare them with the committed references:
yarn loki test
When a test fails, inspect the current screenshot and diff output. Fix unintended changes in the UI or rendering setup. Run yarn loki approve only after confirming a difference is intentional; approving unexplained changes can turn a real regression into the new baseline. Loki can suggest a command to update only failed cases.
For a basic package script, forward Loki options after -- so Yarn or npm passes them through:
{
"scripts": {
"storybook": "start-storybook",
"build-storybook": "build-storybook",
"loki:update": "loki update",
"loki:test": "loki test"
}
}
yarn loki:test -- --requireReference
npm run loki:test -- --requireReference
The exact Storybook start and build script names depend on the project’s Storybook version and setup. Use the scripts already configured in your repository.
4. Run Loki in CI against a static Storybook
A static build avoids depending on a separately managed development server in the CI test step. Build Storybook, then point Loki at the generated directory and require committed references:
yarn build-storybook
yarn loki test --requireReference --reactUri file:./storybook-static
For npm scripts, put -- between the script name and Loki’s arguments:
npm run build-storybook
npm run loki:test -- --requireReference --reactUri file:./storybook-static
Adjust storybook-static if your build uses a different output directory. The file: URI is Loki’s documented way to test a static Storybook. Requiring references makes a missing baseline fail instead of silently creating one during an ordinary CI check. Keep reference updates in a reviewed code change. See Loki’s CI guide and CLI argument reference.
5. Choose configuration and CLI options
Loki accepts command-line settings for the Storybook host and port, Storybook URI, reference directory, current screenshot output, diff output, and diff engine. The documented diff engines are pixelmatch, looks-same, and gm. Use loki --help and the documentation for the installed version to confirm option names and defaults before adding them to scripts; test and update share most arguments, while approve has its own reference and output options.
| Need | Configuration area | Practical guidance |
|---|---|---|
| Test a local server | Host, port, Storybook URI | Start Storybook separately and point Loki to the reachable server. |
| Test a built Storybook | --reactUri |
Use a file: URI such as file:./storybook-static. |
| Organize generated artifacts | Reference, current, and diff paths | Keep committed references distinct from transient current and diff output. |
| Change visual comparison | Diff engine | Choose among pixelmatch, looks-same, and gm; GraphicsMagick is needed for gm. |
| Limit captured stories | Story filtering and screenshot selection | Exclude only stories that cannot be made deterministic or are outside the intended coverage. |
| Handle failed network requests | fetchFailIgnore |
By default Loki fails a test when a story makes a failed network request. Ignore only matching URLs whose failures are expected and irrelevant to the rendered UI. |
| Handle large or unusual layouts | Screenshot cropping and filename formatting | Set selection/cropping and naming behavior deliberately, and check the resulting artifacts before relying on them in CI. |
For exact configuration keys and supported values, use Loki’s configuration guide. Keep exceptions narrow: ignoring a failed request that affects visible content can conceal a real problem.
6. Make screenshots repeatable
A screenshot comparison is sensitive to its rendering environment and story state. Keep the browser target and runtime consistent between local development and CI where practical. Make stories deterministic by stabilizing:
- Animations and transitions: disable or finish them in the test state so capture timing does not change the pixels.
- Time-dependent output: freeze dates or provide fixed values for clocks, relative timestamps, and rotating content.
- Fonts and assets: ensure required fonts and images are available before capture.
- Asynchronous data: use stable fixtures or wait until the intended state has rendered.
- Network behavior: avoid depending on live services where a local fixture can produce the same state reliably.
- Story selection: filter out unsuitable stories only when they cannot reasonably be made stable, and preserve coverage for important components.
Loki’s flaky test guide calls out animation and time sensitivity as causes of varying screenshots. Investigate an intermittent diff rather than approving it automatically.
7. Troubleshooting common failures
| Symptom | Likely cause | What to do |
|---|---|---|
| Loki cannot connect to Storybook | Storybook is not running, the port or host is wrong, or CI cannot reach the server. | Start Storybook before Loki; verify the configured host, port, and URI. For CI, consider building Storybook and using its static file: URI. |
| CI reports a missing reference | The story has no committed baseline, or the reference directory differs from the local setup. | Capture references intentionally with loki update, review the images, and commit them. Keep --requireReference in CI to catch future missing baselines. |
| Many screenshots differ only in CI | Browser/runtime differences, fonts, timing, animation, or environment-dependent content. | Align the browser target and runtime; stabilize fonts, asynchronous states, animations, and time-dependent content, then recapture only after verifying the expected rendering. |
| A test fails on a network request | A story made a request that failed; Loki fails these by default. | Make the story’s data deterministic or fix the request. Use fetchFailIgnore narrowly only when that URL’s failure is expected and does not affect the screenshot. |
The gm diff engine cannot run |
GraphicsMagick is not installed or available to the process. | Install and expose GraphicsMagick in the environment, or choose a supported engine that does not require it. |
| npm/Yarn ignores an option | The package manager consumed the argument instead of forwarding it to Loki. | Use the argument separator: npm run loki:test -- --requireReference or yarn loki:test -- --requireReference. |
| Diffs appear on stories with motion | Capture timing intersects an animation or transition. | Disable motion or ensure capture happens after the story reaches a stable state. |
| A baseline update unexpectedly changes many files | A broad rendering change, changed runtime, unstable stories, or different output settings. | Inspect the diff set and environment first. Approve only the specific intended visual changes. |
8. Performance, reliability, and maintenance
Loki captures stories and compares images locally or through the configured target, so runtime depends on the selected stories, browser target, and environment. The reviewed project documentation provides no benchmark that applies across projects; measure your own suite before setting CI time expectations.
To keep runs useful and maintainable, test the stories that represent important UI states, avoid unnecessary repeated captures, and keep baseline files versioned alongside the code. A consistent browser target and deterministic fixtures improve reliability. If the suite is large, use the documented story filtering and output options to scope work, while ensuring the CI check still covers required stories. Review dependency and target compatibility when upgrading Loki, Storybook, Node.js, or the browser runtime.
Loki is a self-managed screenshot comparison workflow. Storybook also documents Chromatic as a hosted visual testing service, including an official addon for Storybook 7.6 or higher on its version 8 page. Compare hosting, browser coverage, review workflow, and maintenance needs; verify current product requirements before choosing. See Storybook’s visual testing documentation.
Or skip the browser setup
If you need screenshots of web pages outside the Storybook regression suite, ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return a screenshot or PDF. Its clean-shot workflow accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status in headers. AI agents can use its MCP tools: take_screenshot, get_page_info, and capture_pdf. See ScreenshotNeo and the API documentation.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://storybook.js.org -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://storybook.js.org"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://storybook.js.org' });
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));
These calls capture a URL; they do not replace Loki’s comparison of Storybook stories against committed baselines. ScreenshotNeo includes 1,000 screenshots a month free with no card, and paid plans start at $5 for 3,000. Sign up for free.
FAQ
Does Loki create the initial screenshots automatically during tests?
Create initial references with loki update. In CI, use --requireReference so a missing baseline fails rather than being silently established.
Can I use Loki without Docker?
Docker is optional; it is used for Loki’s Chrome Docker target. Select a supported target appropriate to your environment and check the current Loki documentation.
Should every visual difference be approved?
No. First determine whether the change is intended and whether the rendering environment is stable. Approve references only for confirmed UI changes.
Is ScreenshotNeo a replacement for Loki?
No. Loki compares Storybook story screenshots with baselines. ScreenshotNeo captures web pages through an API or MCP server.


