ScreenshotNeo

BlogComparisons

Loki vs Playwright Screenshots: Which Is Better for Visual Regression Testing?

Loki fits Storybook component catalogs; Playwright fits screenshot assertions in browser tests. Choose based on what you need to cover and how your team reviews baselines.

By the ScreenshotNeo team4 October 20269 min read

Direct answer: choose Loki when your visual regression target is a Storybook component catalog and you want a dedicated story-to-baseline workflow. Choose Playwright Test when screenshots belong in page or end-to-end browser tests that your team already runs with Playwright. There is no universal winner: the useful distinction is what you are testing and where you want visual assertions to live.

“Loki vs Playwright screenshots: which is better for visual regression testing?” Both can catch unintended visual changes by comparing a new render against a reference image. Neither removes the need for stable rendering conditions, intentional baseline updates, and human review of diffs.

At a glance

Decision Loki Playwright Test
Best fit Visual checks for Storybook stories and component states. Screenshot assertions within browser journeys or page tests.
Test unit A Storybook story. A page or selected element captured by a Playwright test.
Baseline flow Create references, run comparisons, inspect diffs, approve intentional changes. References are checked into the repository; Git LFS is optional. The first run creates a reference; subsequent runs compare against it. Update intended changes with --update-snapshots.
Environment coverage Project overview lists Chrome in Docker, local Chrome, iOS simulator, and Android emulator. Projects can cover Chromium, Firefox, and WebKit, with snapshot names distinguishing browser/platform or project.
Variation controls Documents async-story and animation handling, with limitations for some animation types. Supports pixel-difference thresholds and a stylesheet for hiding selected volatile content.
Failure review Inspect generated diff images. Trace Viewer can show expected, actual, and diff images with test context.

What Loki does

Loki is a visual regression tool for Storybook projects. Its working unit is a story: start Storybook, capture a reference, run a later comparison, inspect the changed image, and approve a new reference when the change is intentional. The project overview describes Loki as making it easy to test a Storybook project for visual regressions; that is the project’s own description, not independent evidence that it is more accurate or faster than Playwright.

This model suits component libraries where stories already represent the states worth checking: variants, sizes, themes, empty states, and interaction states represented in the catalog. Loki documents commands for updating references and testing them, and recommends checking reference images into the repository. Git LFS is an option if image storage is a concern.

What Playwright screenshot assertions do

Playwright Test can assert that a page or element matches a screenshot baseline:

await expect(page).toHaveScreenshot();

The first execution creates the expected image; later executions compare a new image to it. Snapshot paths and names are configurable. When using multiple browser projects, generated snapshot names distinguish the environments so a baseline from one browser is not silently treated as another’s.

Playwright’s screenshot assertions are useful when the visual result depends on a browser journey: navigate, authenticate, submit a form, open a menu, then assert the resulting page or element. Screenshot comparison stays in the same test runner as the journey and its other assertions.

Which should you choose?

Choose Loki for a Storybook-centered component library

  • Your team treats Storybook stories as the canonical inventory of component states.
  • You want a purpose-built process to generate, compare, inspect, and approve story references.
  • You want visual checks to cover components without writing a separate browser journey for each story.

Loki’s CI guidance includes a static Storybook build and --requireReference, which makes a missing reference fail instead of silently allowing an unreviewed first capture.

Choose Playwright for pages and user journeys

  • Your tests already use Playwright Test and screenshots belong beside navigation and interaction assertions.
  • You need checks for full pages or particular page elements after a real flow.
  • You want its browser projects, screenshot thresholds, volatile-element stylesheet, and trace-based failure context.

Use both when they cover different test units

A team can use Loki for the component catalog and Playwright for page-level journeys if those checks answer different questions. This is a practical inference from their documented scopes; it is not a claim of an official Loki–Playwright integration. Avoid duplicating the same screenshots in both suites without a clear reason, since each baseline adds review and maintenance work.

Set up a Loki baseline workflow

  1. Install Loki using the instructions appropriate for your Storybook and project versions.
  2. Start Storybook locally or build a static Storybook for CI.
  3. Create reference images from the stories you intend to cover.
  4. Review the captured references for missing, unstable, or incorrectly configured states.
  5. Check approved references into the repository; use Git LFS if appropriate for your repository.
  6. Run Loki in CI against those references and inspect diff images when a comparison fails.
build-storybook && loki --requireReference --reactUri file:./storybook-static

The command illustrates the static-build pattern documented by Loki. Check the current Loki documentation for the right install and command details for your Storybook version and CI environment; the official getting-started and CI pages were last shown as updated in 2024, so confirm compatibility before adopting version-specific instructions.

Set up Playwright screenshot assertions

In a Playwright Test file, make an assertion at the point where the visual state is ready. This example assumes the project already has Playwright Test configured and that /dashboard is a page in your application:

import { test, expect } from '@playwright/test';

test('dashboard matches its reference', async ({ page }) => {
  await page.goto('http://127.0.0.1:3000/dashboard');
  await expect(page).toHaveScreenshot();
});

Run the test once to create its reference, then run it again to compare. Review the first reference before treating it as approved. When a UI change is intentional, update snapshots deliberately:

npx playwright test --update-snapshots

Keep the URL, test data, viewport, browser project, and rendering environment consistent between baseline creation and CI. Use Playwright’s current documentation for complete configuration and supported options because its API documentation changes over time.

Keep visual comparisons reliable

Screenshot diffs can change when the rendering setup changes even if the application code does not. Playwright documents variation from host operating system, browser version, settings, hardware, power source, and headless mode. Generate references and run comparisons in the same environment where possible, especially in CI.

  • Pin the rendering environment: use a consistent CI image, browser version, fonts, viewport, and test data.
  • Wait for a real ready state: do not capture while data, fonts, or layout changes are still in progress.
  • Stabilize dynamic content: freeze or seed dates, randomized data, and rotating content where possible.
  • Handle animation intentionally: Loki disables common CSS transitions/animations and requestAnimationFrame by default, but its docs call out looping requestAnimationFrame, GIF, SVG and native Lottie animations, and React Native Animated as limitations that may need to be disabled or skipped.
  • Filter only known noise: Playwright’s maxDiffPixels and custom stylePath can help manage expected variation. A permissive threshold or broad hiding stylesheet can also conceal a real regression, so inspect the affected region.
  • Review every baseline change: an update command records a new expected appearance; it does not decide whether the appearance is correct.

CI, debugging, and maintenance

Loki in CI

Loki documents building a static Storybook and running with --requireReference so that missing references fail. This helps make baseline creation an explicit review step. When a comparison fails, inspect Loki’s generated current, reference, and difference images to identify the changed story and pixels.

Playwright in CI

Playwright recommends running tests regularly in CI and documents CI setup. When a screenshot assertion fails, Trace Viewer provides expected, actual, and diff images alongside surrounding test context. That context can help distinguish an application change from an earlier navigation, loading, or interaction failure.

Maintenance costs

Neither tool has a documented universal speed advantage in the sources reviewed. Runtime depends on how many stories or tests you capture, browser startup and page readiness, and the environment. Loki concentrates work around Storybook stories; Playwright adds screenshot assertions to browser tests. Estimate by running a representative subset in your own CI rather than relying on an unsupported speed ranking.

Plan for reference image storage, review time, environment updates, and intentional baseline changes. Loki references live in the repository, with Git LFS optional. Playwright snapshots also need to be maintained alongside tests. A browser upgrade or CI image change can cause many diffs; treat rendering-environment changes as baseline migrations and review them as such.

Troubleshooting

Symptom Likely cause What to do
Loki reports a missing reference in CI. The reference was never created, was not committed, or is unavailable in the CI checkout. Create and review the reference locally, commit it (or confirm Git LFS retrieval), and retain --requireReference so omissions remain visible.
Loki captures a loading or incomplete story. Asynchronous rendering, data, or assets were not ready at capture time. Make the story deterministic, ensure its async work completes, and use Loki’s documented loading controls for the project version in use.
Loki diffs keep changing around animation. A looping or unsupported animation continues between captures. Disable or skip the animation for visual tests. Check Loki’s documented limitations for the specific animation implementation.
Playwright creates different images on developer machines and CI. OS, browser, fonts, rendering settings, or hardware differ. Generate and compare baselines in the same pinned CI environment; align browser version, viewport, fonts, and test data.
Playwright reports many tiny pixel changes. Dynamic content, antialiasing, or rendering variation affects pixels. Stabilize inputs first. If the remaining variation is expected, tune maxDiffPixels or hide a narrowly selected volatile region with stylePath, then review the resulting diff.
A Playwright screenshot is blank or partial. The assertion ran before navigation or page rendering finished, or the wrong state was reached. Check preceding navigation and interaction assertions, wait on a meaningful ready condition, and inspect the trace’s actual image and test context.
A baseline update makes a test pass but seems suspicious. The new image may reflect an unintended change or a broken setup. Compare expected, actual, and diff images; confirm the environment and test state; accept the new reference only after review.

Or skip the browser setup

For a one-off screenshot or an external page capture, ScreenshotNeo returns an image or PDF from one API request. This does not replace Loki or Playwright’s baseline comparisons for your application tests; it is an alternative when you need a screenshot without setting up browser capture code.

ScreenshotNeo API documentation · ScreenshotNeo request 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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

ScreenshotNeo accepts cookie banners 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, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000. See the docs for request options, including formats, viewport, full-page capture, element selection, waiting, and output controls.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.

FAQ

Can Loki test an application without Storybook?

Loki’s documented purpose and workflow center on Storybook projects. If your target is a page journey without a Storybook story, Playwright screenshot assertions are the more direct fit of these two.

Do visual screenshots prove a layout is accessible?

No. A screenshot comparison checks rendered appearance. Keep accessibility assertions and assistive-technology testing as separate parts of your test strategy.

Is WebP supported for Playwright screenshot baselines?

Playwright’s default screenshot format is PNG. Its docs describe lossless WebP when the snapshot filename uses the .webp extension.

Which one is more accurate or faster?

The official documentation reviewed provides no controlled comparative benchmark for accuracy, speed, or flake rate. Choose by test unit and measure runtime and noise in your own pinned CI setup.