Use Puppeteer to render a page and capture its pixels, Jest to run the test, and jest-image-snapshot to compare the screenshot buffer with a saved image baseline. The first run creates the baseline; later runs flag visual differences for review. This is different from Jest’s standard text snapshots, which serialize values rather than compare rendered pixels.
What each tool does—and what it tests
- Puppeteer controls a browser: it opens a route, sets up the page, and captures a screenshot.
- Jest runs the test and reports whether its expectations pass.
jest-image-snapshotadds thetoMatchImageSnapshotmatcher, which compares the screenshot image buffer with a stored baseline.
Use a visual regression test when the rendered appearance matters. Use ordinary Jest snapshots for serialized values such as component output or data. The two approaches can complement each other; neither replaces the other. Jest describes visual regression tools as taking screenshots and comparing the resulting images pixel by pixel: Jest Snapshot Testing.
As an Amazon Associate I earn from qualifying purchases.
Install and configure the image matcher
Install the matcher as a development dependency:
npm i --save-dev jest-image-snapshot
Register its matcher in the test module or a Jest setup file that runs before your tests:
const { toMatchImageSnapshot } = require('jest-image-snapshot');
expect.extend({ toMatchImageSnapshot });
The package README states a peer dependency range of Jest >=20 and <=29. Compatibility is version-sensitive: check the package metadata and your lockfile before pairing it with another Jest version, especially Jest 30. The package’s own documentation is at the jest-image-snapshot README.
Write a Puppeteer screenshot test
This illustrative CommonJS test shows the core pattern. It assumes your application is already reachable at the URL and that your Jest environment can provide a Puppeteer browser instance; server startup, browser setup, readiness conditions, and cleanup depend on your project.
const { toMatchImageSnapshot } = require('jest-image-snapshot');
expect.extend({ toMatchImageSnapshot });
it('renders the page consistently', async () => {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto('http://localhost:3000', { waitUntil: 'networkidle0' });
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
await page.close();
});
The viewport and URL here are examples, not universal settings. Choose dimensions and a readiness condition that reflect the state your test intends to protect. A real test should also close the page if navigation or the assertion fails, typically with a try/finally block, and should launch and close its browser through the project’s test setup.
Create, review, and update image baselines
First run
On the first comparison, jest-image-snapshot stores an image baseline under __image_snapshots__ by default. Commit the baseline with the test so that reviewers and CI use the same reference. Jest likewise recommends committing snapshots alongside the modules and tests they cover.
Free tools Windows power users keep installed
One-click scans. No signup required.
When a test fails
- Open the baseline, newly received screenshot, and generated diff artifacts.
- Decide whether the difference is a product regression, rendering noise, or an intentional UI change.
- Fix a regression or stabilize the test when appropriate. If the new appearance is intentional, update only the affected baseline after reviewing it.
Do not update baselines automatically just to make a failing test pass. A baseline is an expected visual state, not proof that the current output is correct. Jest’s documentation notes that it does not automatically write snapshots in CI unless an update option is explicitly used.
Make captures deterministic
Visual comparisons are sensitive to differences in what the browser renders. Control the inputs that matter to your page and keep them consistent between local runs and CI:
- Viewport and device scale: set the same dimensions and scale for every run.
- Page state and data: use fixed fixtures and predictable dates instead of user-specific or changing values.
- Readiness: wait for a meaningful selector or application state rather than relying on an arbitrary delay. Network-idle waiting can help, but may not suit pages with persistent network activity.
- Animations: disable or finish them when motion is not what the test is intended to check.
- Fonts and environment: make browser, fonts, and operating environment consistent. The Think Company example uses Docker to reduce differences between native operating systems and CI; it is an implementation choice, not a requirement for every project.
- Dynamic regions: make rotating banners, ads, timestamps, or other changing content deterministic, or remove or mask them when doing so preserves the behavior under test. The matcher README demonstrates removing banner elements with Puppeteer before capture.
Removing a region can also conceal a real regression. Keep it in the screenshot whenever its content or layout is part of the behavior you need to verify.
Choose comparison settings deliberately
The matcher documents pixelmatch as the default comparison method and SSIM as another option. Its README lists a default per-pixel threshold of 0.01 and an overall failure threshold of zero. These are library defaults, not universally recommended settings.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- Pixel sensitivity: how much difference between individual pixels is tolerated.
- Overall failure threshold: how much of the image may differ before the test fails.
- Comparison method: pixel-by-pixel comparison or structural similarity (SSIM).
- Diagnostics: where snapshots and diffs are saved, and whether the output includes the baseline, received image, and diff.
- Noise policy: whether to stabilize, mask, or blur small rendering variations.
A more permissive threshold may reduce noisy failures but can let a genuine visual change pass. Tune settings against representative pages, inspect actual diffs, and keep the chosen tolerance appropriate to what the test is meant to catch. The package README documents custom snapshot directories, diff controls, thresholds, comparison methods, and baseline updates.
Troubleshoot common failures
The test cannot load the page
Confirm the application server is running and the test URL resolves from the test process. If the route redirects or depends on authentication, establish that state before capturing. Make sure the test waits for the expected page state rather than taking a screenshot immediately after navigation.
Rank #4
Images differ on a developer machine and in CI
Check viewport, device scale, browser and operating system, installed fonts, data, and animation state. Make the rendering environment consistent; a containerized setup is one option demonstrated by the Think Company example.
The baseline changes on every run
Look for timestamps, randomized or user-specific content, rotating banners, asynchronous layout changes, and unfinished animations. Replace variable inputs with fixed fixtures or remove only the dynamic regions that are outside the test’s purpose.
A small rendering change fails every test
Inspect the diff first. If the change is irrelevant noise, stabilize the source or adjust comparison settings for the affected test. Raising tolerance globally can hide meaningful regressions, so prefer targeted changes.
The matcher or Jest version is incompatible
Check the installed package version, its peer dependency metadata, and the lockfile. The README’s stated Jest range ends at version 29; do not assume support for another version from Jest’s general snapshot features.
Best Value
Or skip the browser setup
If you need a screenshot from a URL rather than a test of your own browser-rendered application, ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns an image or PDF; for example, this cURL request saves a WebP screenshot. See the ScreenshotNeo API documentation for 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
- Cookie banners are accepted and removed, along with known newsletter popups and chat widgets; each of these steps can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for AI agents and MCP clients. - The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month without a card.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsQuick Recap
Sources
- Jest, Snapshot Testing (page last updated August 28, 2026).
- American Express Open Source Community, jest-image-snapshot README.
- Think Company, Visual regression testing with Jest, Puppeteer and jest-image-snapshot.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




