ScreenshotNeo

BlogHow-to

How to Update Reference Screenshots in BackstopJS Safely

Compare BackstopJS test captures before approving them, limit updates to reviewed screenshots, and protect existing baselines from accidental replacement.

By the ScreenshotNeo team4 October 20266 min read

To update BackstopJS reference screenshots safely, run backstop test, review the visual report, then run backstop approve to promote the reviewed captures from the latest test batch. Use an approval filter when only some screenshots should change. Avoid backstop reference for routine updates: it skips comparison and deletes existing reference images by default. Keep your baselines recoverable and inspect the files after approval.

What each BackstopJS command does

Command Purpose Safety consideration
backstop test Captures test screenshots and compares them with current references in a visual report. Review the report before changing baselines. A scenario-label filter can limit which scenarios are captured.
backstop approve Promotes screenshots from the most recent test batch to the reference collection. Only approve after review. A filename-regex filter can restrict the captures that are promoted.
backstop reference Generates references directly, without first comparing them to the existing set. Existing reference images are deleted by default. The documented --i option avoids deleting reference-directory files first; verify the installed version’s behavior.

In short: use test followed by approve for reviewed updates. Use reference only when you deliberately want to generate a baseline without the comparison step.

Safe update workflow

  1. Check the working tree and environment. Confirm which BackstopJS configuration and application build you intend to capture. Make the current references recoverable through version control or another backup before promoting changes.
  2. Capture and compare. Run backstop test. If you need to scope the test, use the scenario-label filter supported by your configuration and BackstopJS version.
  3. Inspect the report. Review the reference, test, and difference views. For each changed capture, confirm the URL, environment, viewport, content, and page state are expected. A changed screenshot can reflect an application update, but also a wrong environment, failed navigation, incomplete loading, or inconsistent rendering.
  4. Approve only reviewed captures. Run backstop approve after the differences are understood. If only a subset is intended, pass --filter=<image_filename_regex> using a pattern that matches only those capture filenames.
  5. Inspect the promoted files. Review the reference-image changes in version control or compare them with your backup. This confirms the update’s scope and gives you a recovery path if an unintended image was promoted.

Runnable command examples

Run BackstopJS from the project directory that contains its configuration. The standard reviewed-update sequence is:

backstop test
# Review the report and confirm each intended change.
backstop approve

To test a subset by scenario label, use the filter syntax supported by your installed CLI, for example:

backstop test --filter=checkout

Approval filtering is a separate step and uses an image filename regular expression, not the scenario-label filter:

backstop approve --filter='checkout.*'

Choose a pattern that matches only the intended output filenames. Check the filenames in the report or generated test directory first; do not assume a scenario label and an image filename have identical forms.

If you ran the test with a custom configuration file, pass that same file when approving so the workflow continues with the same configuration:

backstop test --configPath=backstop.staging.json
# Review the report for this configuration.
backstop approve --configPath=backstop.staging.json

BackstopJS CLI option spelling can differ by installed version. Check the help output and project documentation for your version before relying on a particular flag.

Filters, configuration, and rendering consistency

Do not confuse the two filters

The test filter scopes capture by scenario label. The approval filter scopes promotion by image filename regular expression. A narrow test does not itself guarantee that approval will be narrow, so verify the approval filter against actual filenames.

Continue with the same configuration

Use the configuration file from the test when you approve. Otherwise, a different set of scenarios or settings may be used during promotion. If your workflow uses a custom config path, record it with the test command so the approval command can repeat it.

Keep rendering conditions stable

The BackstopJS README recommends Docker rendering to help maintain consistency across environments. Consistent rendering reduces environment-related differences, but does not guarantee identical results in every setup. Keep the target environment, viewport, fonts, data, and page state consistent when comparing captures.

When to use backstop reference

Use direct reference generation only when you intend to create baselines without first reviewing a comparison report. The npm documentation says this command deletes existing reference images by default before creating new ones. That makes it materially different from approving reviewed test captures.

The npm documentation describes --i as an incremental option that avoids first deleting files in the reference directory. Confirm that the installed version supports the flag and understand its behavior before using it. Incremental generation can leave older images in place, so it is especially important to verify which files belong to the current baseline set.

# Deliberate direct baseline generation; destructive by default.
backstop reference

# Incremental mode described in the npm documentation; verify your version.
backstop reference --i

Common errors and fixes

Symptom Likely cause What to do
Many unrelated differences appear The application environment, data, viewport, or page state changed between reference and test capture. Confirm the URL and environment, restore consistent test data and state, then rerun the test before approving.
The approved images are not the ones you reviewed Approval promoted captures from a newer test batch, or a different configuration was used. Run the test, review that batch, and approve it before running another test. Pass the same custom config path to both commands.
Some intended images were not updated The approval filename filter did not match their generated filenames. Inspect the filenames and adjust the regex; remember that approval filtering uses filenames, while test filtering uses scenario labels.
Unexpected reference files disappeared backstop reference was used; it deletes existing references by default. Restore the reference files from version control or backup. For future reviewed changes, use the test-and-approve workflow.
The same page differs across machines Rendering conditions vary between environments. Align the capture environment and consider Docker rendering, which the README recommends for helping consistency.
A CLI flag is rejected or behaves differently Documentation and CLI options can vary by installed BackstopJS version. Check the installed version’s help and documentation. Verify --i behavior before using it on important references.

Performance, reliability, and cost

The safe workflow adds the time needed to capture and inspect a report before promotion. Scope test captures when only a subset of scenarios needs review, and scope approval separately when only a subset of files should be promoted. Avoid rerunning tests between review and approval unless you intend to review the newer batch: approval promotes images from the most recent test batch.

BackstopJS’s documented workflow does not specify a universal visual-difference threshold that makes approval safe. Make the decision based on the expected application change and the actual reference, test, and difference views. Keep baseline files in version control or another recoverable location; this is practical safety guidance inferred from the documented replacement behavior, not a stated BackstopJS requirement.

Or skip the browser setup

For standalone website captures, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. It does not replace BackstopJS’s reference comparison and approval workflow; it can provide captures without setting up a browser automation stack. 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
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}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

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

FAQ

Does approving a change edit my application’s code?

No. Approval updates the reference screenshot collection used by later visual comparisons.

Can I approve only one screenshot?

Yes. Use backstop approve --filter=<image_filename_regex> with a pattern narrow enough to match that capture’s filename.

Should I approve every difference if the test command succeeds?

No. A successful command means the comparison ran; it does not establish that each visual change is intended. Review the report before promotion.

Will Docker make screenshots identical everywhere?

The project README recommends Docker to help rendering consistency. It does not guarantee identical results in every environment.

Sources