Screenshot any URL via API — before and after every deploy. Pipe the images into your existing diff tool. No browser to configure, no flaky screenshot infrastructure to maintain.
100 calls/month free · No credit card · Works in any CI/CD pipeline
The tooling works locally. Production is a different story.
Font rendering, animation timing, and subpixel differences vary between OS and GPU — so screenshots taken on macOS don't match CI Linux. Tests fail randomly.
The Chrome version on your CI runner is different from local. Screenshots differ by 1–3% even on identical pages. Threshold tuning becomes a full-time job.
Running Chromium in CI means system library dependencies, sandbox flags, memory limits, and 300MB+ downloads per fresh runner. Complex for zero business value.
SnapAPI provides consistent, reproducible screenshots from the same infrastructure every time.
Call the screenshot endpoint for each critical page. Save the PNG files as the visual baseline.
Call the same endpoint again after the deploy completes. Same URL, same dimensions, same API.
Use any pixel-diff library (pixelmatch, resemblejs, or a SaaS like Percy) to compare. SnapAPI just provides the screenshots.
The core pattern — swap in any diff library.
// visual-regression.js — run before/after deploys in CI // npm install snapapi-sdk pixelmatch pngjs const snap = require('snapapi-sdk'); const pixelmatch = require('pixelmatch'); const { PNG } = require('pngjs'); const fs = require('fs'); const api = new snap.SnapAPI(process.env.SNAPAPI_KEY); const PAGES = ['https://myapp.com', 'https://myapp.com/pricing']; async function captureBaseline() { for (const url of PAGES) { const slug = new URL(url).pathname.replace(/\//g, '-') || 'home'; const buf = await api.screenshot({ url, width: 1280, height: 800, format: 'png' }); fs.writeFileSync(`baseline${slug}.png`, buf); } } async function compareWithBaseline() { let failed = false; for (const url of PAGES) { const slug = new URL(url).pathname.replace(/\//g, '-') || 'home'; const current = PNG.sync.read(await api.screenshot({ url, width: 1280, height: 800 })); const baseline = PNG.sync.read(fs.readFileSync(`baseline${slug}.png`)); const diff = new PNG({ width: current.width, height: current.height }); const changed = pixelmatch(baseline.data, current.data, diff.data, current.width, current.height, { threshold: 0.1 }); const pct = (changed / (current.width * current.height) * 100).toFixed(2); if (changed > 100) { // more than 100 pixels different console.error(`FAIL ${url} — ${pct}% changed (${changed} pixels)`); fs.writeFileSync(`diff${slug}.png`, PNG.sync.write(diff)); failed = true; } else { console.log(`OK ${url} — ${pct}% changed`); } } if (failed) process.exit(1); // fail CI step } // Run: CAPTURE=1 for baseline, nothing for comparison process.env.CAPTURE ? captureBaseline() : compareWithBaseline();
SnapAPI always runs the same Chromium version on consistent infrastructure — no per-runner variation, no subpixel drift between OS environments.
SnapAPI provides the screenshots. You use whatever diff tool you already have.
Free API key — 100 calls/month, works in any CI environment.
Get Free API Key →