RenderShotGet a free API key

Visual regression testing in CI without running a browser

A UI change ships, and a button quietly disappears on mobile. Visual regression testing catches that — but maintaining headless Chrome in CI is its own job. Here's how to do it with one API call instead.

The problem with DIY visual testing

The usual setup: install Playwright or Puppeteer in CI, launch Chromium, screenshot pages, diff them against committed baselines. It works, until it doesn't:

The alternative: a visual diff API

Instead of capturing and comparing yourself, call a visual diff API: send a baseline URL (production) and a candidate URL (your preview/staging deploy), and get back how much changed. Metrics first — you only download an image when something actually moved.

curl --request POST \
  --url https://screenshot-e-pdf-render.p.rapidapi.com/v1/diff \
  --header 'X-RapidAPI-Key: YOUR_KEY' \
  --header 'X-RapidAPI-Host: screenshot-e-pdf-render.p.rapidapi.com' \
  --header 'Content-Type: application/json' \
  --data '{
    "baseline":  { "url": "https://prod.example.com/pricing" },
    "candidate": { "url": "https://preview.example.com/pricing" },
    "options": { "diffOutput": "metrics", "fullPage": true,
                 "ignoreSelectors": [".cookie-banner", "[data-dynamic]"] }
  }'
{ "changed": true, "difference_percentage": 2.41,
  "different_pixels": 18960, "total_pixels": 786432, "fast_path": false }

Fail the pull request on regressions

Drop this into GitHub Actions. It fails the build when the page changed more than 1%:

name: Visual diff
on: [pull_request]
jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - name: Compare production vs preview
        env:
          RAPIDAPI_KEY: ${{ secrets.RAPIDAPI_KEY }}
        run: |
          curl -s --request POST \
            --url https://screenshot-e-pdf-render.p.rapidapi.com/v1/diff \
            --header "X-RapidAPI-Key: $RAPIDAPI_KEY" \
            --header "X-RapidAPI-Host: screenshot-e-pdf-render.p.rapidapi.com" \
            --header 'Content-Type: application/json' \
            --data '{"baseline":{"url":"https://prod.example.com"},"candidate":{"url":"https://preview.example.com"},"options":{"diffOutput":"metrics","fullPage":true}}' \
            -o diff.json
          PCT=$(jq -r '.difference_percentage' diff.json)
          echo "Difference: ${PCT}%"
          awk "BEGIN{exit !(${PCT} > 1.0)}" \
            && { echo '::error::Visual regression > 1%'; exit 1; } \
            || echo 'Within threshold.'

Killing false positives

When DIY still wins

If you need component-level snapshots inside a test runner (Storybook, jsdom), a local tool is the right call. The API approach shines for page-level checks across environments — pre-deploy diffs, production monitoring and cross-device comparisons — without owning browser infrastructure.

Try it

RenderShot's /v1/diff is metrics-first with ignore regions, selectors and a SHA-256 fast path. Free tier, no card.

Start free →Visual Diff API details