ScreenshotNeo

BlogComparisons

Loki vs BackstopJS for Website Screenshot Testing

Compare Loki and BackstopJS by test inputs, workflows, targets, and review needs. Choose the tool that fits your team’s existing screenshot tests.

By the ScreenshotNeo team4 October 20269 min read

Short answer: Choose Loki if your visual tests are already defined as Storybook stories. Choose BackstopJS if you want to test a list of web page URLs and scenarios, especially when those scenarios need interaction steps. Neither is universally better; the deciding factors are where your test cases live, which targets you need to render, and how your team reviews changes.

This comparison uses the projects’ official documentation. It is not a hands-on benchmark or a claim that one tool is faster, more reliable, or easier to maintain. Check the current project documentation and versions before adopting either tool.

How to choose

Your situation Start by evaluating Reason
Your UI is represented by Storybook stories and you want to check components in those stories Loki Stories are Loki’s unit of work.
Your checks are a set of page URLs with viewport settings and scenarios BackstopJS Its configuration is organized around endpoints, screen settings, selectors, and scenarios.
You need explicit interaction sequences during page checks BackstopJS Its README documents scenario interaction scripts.
You need Storybook visual checks in CI Loki Loki documents using a built Storybook artifact for CI.
You need to capture mobile targets through simulators or emulators Check Loki’s current target support The Loki repository lists iOS simulator and Android emulator among its targets; verify the released version and your environment.

Both workflows use reference screenshots. In either case, budget for reviewing intended changes and maintaining the baselines over time.

What each tool tests

Loki: Storybook stories

Loki describes itself as visual regression testing for Storybook. Its documented process expects Storybook, or a simulator or emulator for mobile targets, to be available. Loki captures tested stories, compares them with reference images, writes current and difference images, and supports approving intentional updates. It does not start the Storybook server for you. The getting-started guide suggests storing reference images in the repository and mentions Git LFS as an option. Loki project README · Loki getting started

BackstopJS: URLs and scenarios

BackstopJS centers its configuration on web endpoints or document scenarios, screen settings, selectors, and interactions. Its documented workflow captures test screenshots against approved references and provides a browser report for inspecting references, test images, and differences. It also documents mismatch thresholds, interaction scripts, and CI reports. The project README describes its purpose as automating visual regression testing by comparing screenshots over time. BackstopJS project README

Feature and workflow comparison

Question Loki BackstopJS
What defines a test? A Storybook story. A configured URL or document scenario.
What must be available? A running or built Storybook for the capture workflow, or the relevant mobile simulator or emulator target. The configured web endpoints and the browser rendering environment.
Can a test describe interactions? The documented core flow focuses on capturing stories. The README documents scenario interaction scripts.
How are changes reviewed? Inspect current and difference images, then approve intentional reference updates. Inspect the in-browser report, then approve intentional reference updates.
What targets are documented? The repository lists Chrome in Docker, Chrome in AWS Lambda, local Chrome, iOS simulator, and Android emulator. The README describes Chrome Headless and integrated Docker rendering.

These are documented capabilities, not a guarantee that a particular current release supports every combination. Check compatibility with your Node.js, Storybook, browser, operating system, and CI setup.

Set up a representative evaluation

Do not decide from a feature list alone. Pick a small set that reflects the work you actually need to protect: several representative components or stories for Loki, or a few important URLs and interaction scenarios for BackstopJS. Include a page with dynamic content if that is part of your real test surface, and decide how the team will review and approve baseline changes.

Loki setup outline

  1. Confirm the current Loki prerequisites and support for your Storybook version. The getting-started guide lists Node 16+; that guide was last updated 2024-08-27, so verify this version-sensitive requirement against current documentation.
  2. Install Loki and initialize its configuration:
yarn add loki --dev
yarn loki init
  1. Start Storybook so Loki can reach it. Loki does not launch the server for you.
  2. Create reference images, capture after a UI change, inspect differences, and approve only changes you intended.
yarn loki update
yarn loki test

The guide notes Docker as an option for the chrome.docker target and GraphicsMagick for the gm diff engine. Treat those as configuration choices to confirm for your setup, not mandatory dependencies for every Loki run. The documentation also describes React Native integration with simulator or emulator use. See the Loki getting-started guide for the current configuration details.

Loki in CI

Loki’s CI guide shows building Storybook and running against the generated artifact. Its example requires reference images, so a missing baseline fails in this typical CI setup:

build-storybook && loki --requireReference --reactUri file:./storybook-static

Adapt the command to your package scripts and artifact path. Keep baseline updates deliberate: a CI failure caused by a missing reference is different from a pixel difference against an existing reference. See the Loki CI guide.

BackstopJS setup outline

  1. Define the page endpoints, screen settings, selectors, and scenarios that represent the checks you need.
  2. Initialize the project configuration, capture references, run tests, inspect the report, and approve intentional changes.
backstop init
backstop test
backstop approve

Run backstop approve after reviewing the report and confirming that the observed change is expected. The README documents Chrome Headless and integrated Docker rendering. Confirm the exact configuration and current command behavior against the BackstopJS README.

Baseline review and CI practices

  1. Make the render environment repeatable. Pin relevant dependency and browser versions where your setup allows it, and use the same fonts, data, viewport dimensions, and rendering environment for reference and test captures.
  2. Keep test inputs purposeful. Stories are a natural inventory for component states; URLs and scenarios are a natural inventory for page flows. Avoid duplicating checks without a clear coverage reason.
  3. Review diffs before updating references. A changed screenshot can signal an intended design update, a real regression, or environmental variation. Do not approve a broad batch without inspecting representative differences.
  4. Fail clearly on missing baselines. For Loki’s documented CI pattern, --requireReference makes missing references fail instead of quietly treating a fresh image as an established baseline.
  5. Give baseline changes an owner. Agree who reviews visual changes and how the pull request records intentional updates. Both tools depend on reference images, so approvals are part of ongoing maintenance.

Reliability, performance, and cost considerations

The reviewed official sources do not provide a comparable benchmark or decision-relevant performance statistics. Do not choose based on assumed speed, flakiness, or maintenance burden. Measure representative runs in your own CI environment if runtime affects the decision.

  • Reproducibility: browser version, OS, fonts, device scale, viewport, loaded data, and timing can affect captures. Keep these inputs consistent between baseline creation and CI.
  • Dynamic pages: animations, rotating content, live timestamps, asynchronous loading, and personalized data can create noisy diffs. Stabilize test data and page state where possible, and capture only after the page reaches the state your test intends to verify.
  • CI resources: browser processes, containers, and simulator or emulator targets consume runner time and resources. Evaluate the actual target configuration you plan to keep.
  • Maintenance cost: both options require reference review and updates when changes are intentional. Loki’s project README states that its aim includes low maintenance and reproducible tests; this is the project’s stated aim, not independent evidence of results in every environment.
  • Licensing and project status: review each project’s current repository, license, release, and compatibility information before adopting it. The reviewed sources do not establish a directly comparable release or maintenance status for both projects.

Troubleshooting

Symptom Likely cause What to check
Loki cannot capture stories Storybook is not running or the configured URI does not point to the available server or artifact. Start Storybook before capture, or check the URI and artifact path in the CI command.
Loki CI fails because references are missing The reference images were not generated or made available to the job; the documented CI example uses --requireReference. Generate and commit or otherwise provide the intended references, and verify the reference location used by CI.
Captures differ across local and CI runs Different browser, operating system, fonts, viewport, or rendering setup can alter pixels. Align the rendering configuration; consider a consistent container or other supported environment, then regenerate references only after review.
BackstopJS checks the wrong page or state Endpoint, selector, screen setting, or interaction sequence does not match the intended scenario. Inspect the scenario configuration and use the report to confirm the captured page and state.
Visual diffs are noisy on changing pages Dynamic data, animation, or inconsistent load timing changes between runs. Stabilize data and state, remove avoidable animation in the test environment, and wait for the intended content before comparing.
Unexpectedly many reference updates appear A broad UI change, changed rendering environment, or unstable test input affected multiple captures. Review a sample of diffs, compare environment changes, and separate expected visual changes from rendering noise before approving.

ScreenshotNeo as an alternative to try first

Loki and BackstopJS are visual regression testing tools that compare captures with references. If your immediate need is to obtain clean website screenshots through an API, try ScreenshotNeo first: it returns PNG, JPEG, WebP, or PDF from one GET request, accepts cookie consent and removes known consent banners, newsletter popups, and chat widgets before capture, and bills only clean shots. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; the response identifies the page verdict and billing status in headers. Its MCP server provides screenshot tools for AI agents. ScreenshotNeo is not a replacement for maintaining visual regression baselines in Loki or BackstopJS.

For team selection, trial Loki against representative Storybook stories if stories are your test inventory; trial BackstopJS against representative URLs and interaction scenarios if page flows are your inventory. Compare review ownership, baseline churn, reproducibility, target support, and CI fit on your own stack.

FAQ

Can I use Loki without Storybook?

Loki’s documented workflow is built around Storybook stories. If your tests are page URLs and scenarios, BackstopJS’s documented model is a closer fit.

Does Loki start Storybook during a test?

No. Its getting-started documentation says Storybook must be available for the capture; in CI, the guide shows building Storybook and pointing Loki at the artifact.

Which tool is faster?

The reviewed sources do not establish a comparable speed result. Run both against representative cases in your own environment if runtime is a deciding factor.

Can I use either tool in CI?

Both projects document CI-oriented workflows. Check their current guides and verify browser and runtime compatibility for your particular pipeline.

Does approving a baseline mean the UI is correct?

No. Approval records that a visual change is accepted as a reference. A reviewer still needs to determine whether the change matches the intended design.

Or skip the browser setup

Use ScreenshotNeo when you need a clean screenshot from a URL without setting up a browser capture stack. The API accepts a URL and can return PNG, JPEG, WebP, or PDF. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed. An MCP server lets AI agents use its screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is available on every plan. See the API documentation for supported parameters and options.

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}`);

Sign up for 1,000 free screenshots a month, with no card required.