[{"data":1,"prerenderedAt":771},["ShallowReactive",2],{"navigation_docs":3,"-compare":93,"-compare-surround":217,"tools":222},[4,41,46,89],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":40},"Learn","i-lucide-book-open","\u002Flearn","1.learn",[10,15,20,25,30,35],{"title":11,"path":12,"stem":13,"icon":14},"What visual regression testing is","\u002Flearn\u002Fwhat-is-visual-regression-testing","1.learn\u002F1.what-is-visual-regression-testing","i-lucide-eye",{"title":16,"path":17,"stem":18,"icon":19},"How image diffing works","\u002Flearn\u002Fhow-image-diffing-works","1.learn\u002F2.how-image-diffing-works","i-lucide-diff",{"title":21,"path":22,"stem":23,"icon":24},"Why screenshots flake","\u002Flearn\u002Fwhy-screenshots-flake","1.learn\u002F3.why-screenshots-flake","i-lucide-shuffle",{"title":26,"path":27,"stem":28,"icon":29},"Baselines and approval","\u002Flearn\u002Fbaselines-and-approval","1.learn\u002F4.baselines-and-approval","i-lucide-check-check",{"title":31,"path":32,"stem":33,"icon":34},"Running in CI","\u002Flearn\u002Frunning-in-ci","1.learn\u002F5.running-in-ci","i-lucide-workflow",{"title":36,"path":37,"stem":38,"icon":39},"Choosing a tool","\u002Flearn\u002Fchoosing-a-tool","1.learn\u002F6.choosing-a-tool","i-lucide-list-checks",false,{"title":42,"path":43,"stem":44,"icon":45},"Compare the tools","\u002Fcompare","2.compare","i-lucide-scale",{"title":47,"path":48,"stem":49,"children":50,"icon":53},"Manifest","\u002Fmanifest","3.manifest\u002F1.index",[51,54,59,64,69,74,79,84],{"title":52,"path":48,"stem":49,"icon":53},"The run manifest","i-lucide-file-json",{"title":55,"path":56,"stem":57,"icon":58},"The format","\u002Fmanifest\u002Fformat","3.manifest\u002F2.format","i-lucide-file-code",{"title":60,"path":61,"stem":62,"icon":63},"Reading manifests","\u002Fmanifest\u002Freading","3.manifest\u002F3.reading","i-lucide-book-open-check",{"title":65,"path":66,"stem":67,"icon":68},"Merging the manifests of a run","\u002Fmanifest\u002Fmerging","3.manifest\u002F4.merging","i-lucide-merge",{"title":70,"path":71,"stem":72,"icon":73},"Writing manifests","\u002Fmanifest\u002Fwriting","3.manifest\u002F5.writing","i-lucide-pencil-line",{"title":75,"path":76,"stem":77,"icon":78},"Converting to and from other formats","\u002Fmanifest\u002Fconverting","3.manifest\u002F6.converting","i-lucide-arrow-left-right",{"title":80,"path":81,"stem":82,"icon":83},"Reference","\u002Fmanifest\u002Freference","3.manifest\u002F7.reference","i-lucide-list",{"title":85,"path":86,"stem":87,"icon":88},"Schema reference","\u002Fmanifest\u002Fschema","3.manifest\u002F8.schema","i-lucide-braces",{"title":90,"path":91,"stem":92,"icon":14},"Viewer","\u002Fviewer","4.viewer",{"id":94,"title":42,"body":95,"description":210,"extension":211,"links":212,"meta":213,"navigation":214,"path":43,"seo":215,"stem":44,"__hash__":216},"docs\u002F2.compare.md",{"type":96,"value":97,"toc":204},"minimark",[98,102,129,132,137,189,193],[99,100,101],"p",{},"Every row is one YAML file in the repository, with a date it was last checked and links to the vendor's own documentation for each claim. Pricing is listed as a model, never as numbers, because numbers are the first thing to go stale. Click a row for the details, the sources, and a link to correct it.",[99,103,104,105,109,110,114,115,118,119,123,124,128],{},"The column most comparisons leave out is ",[106,107,108],"strong",{},"machine-readable results",": what a tool running ",[111,112,113],"em",{},"after"," the tests can read. Most tools leave you image folders and nothing else, hosted services keep the results inside their app, and a few write a JSON report. The ",[106,116,117],{},"manifest"," column says whether a tool writes the ",[120,121,122],"a",{"href":48},"run manifest"," itself, has a converter in ",[125,126,127],"code",{},"visual-regression-manifest",", or fits the generic image-triple converter.",[130,131],"tools-compare",{},[133,134,136],"h2",{"id":135},"how-to-read-it","How to read it",[138,139,140,159,177,183],"ul",{},[141,142,143,146,147,150,151,154,155,158],"li",{},[106,144,145],{},"Runs",": where the comparison happens. ",[111,148,149],{},"Local"," tools diff on the machine running the tests; ",[111,152,153],{},"cloud"," services take screenshots or DOM snapshots and diff on their side; ",[111,156,157],{},"self-hosted"," means you run the service.",[141,160,161,164,165,168,169,172,173,176],{},[106,162,163],{},"Review",": where a human looks at the diff. ",[111,166,167],{},"Local files"," means opening the images yourself; ",[111,170,171],{},"pull request"," means a comment or check on the PR; ",[111,174,175],{},"web app"," means the service's own UI.",[141,178,179,182],{},[106,180,181],{},"Baselines",": where the reference images live. In the repository they version with the code; in a service they version with the service's notion of a branch.",[141,184,185,188],{},[106,186,187],{},"Pricing",": free, a free tier with paid plans, per screenshot, per seat, or a custom quote. Check the vendor for the numbers.",[133,190,192],{"id":191},"adding-or-correcting-a-tool","Adding or correcting a tool",[99,194,195,196,199,200,203],{},"Open a pull request with a YAML file under ",[125,197,198],{},"apps\u002Fsite\u002Fdata\u002Ftools\u002F",". Every field is validated at build time, every claim needs a source URL from the tool's own documentation, and ",[125,201,202],{},"lastVerified"," is the day you checked. Vendor contributions are welcome and are held to the same standard as everyone else's.",{"title":205,"searchDepth":206,"depth":206,"links":207},"",2,[208,209],{"id":135,"depth":206,"text":136},{"id":191,"depth":206,"text":192},"Runner integrations, hosted review services, diff engines and mobile tools, compared on facts from their own docs.","md",null,{},{"icon":45},{"title":42,"description":210},"fAHrotsH9XRDsM9dNMHIbi916Xyai_e15cVUBkHwJyY",[218,220],{"title":36,"path":37,"stem":38,"description":219,"icon":39,"children":-1},"The four questions that narrow the field, the trade-offs between local tools and hosted services, and what to look for so you can change your mind later.",{"title":52,"path":48,"stem":49,"description":221,"icon":53,"children":-1},"One JSON file per test run that lists every screenshot comparison, built upon CTRF, written by several tools and read by PR bots and review apps.",[223,254,276,299,315,330,347,361,377,397,416,435,449,465,488,504,520,535,550,569,584,605,623,638,658,673,689,704,719,736,754],{"id":224,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":227,"extension":228,"hosting":153,"lastVerified":229,"license":212,"machineReadableResults":230,"manifestSupport":231,"meta":232,"name":233,"notes":234,"openSource":40,"pricingModel":236,"reviewSurface":237,"runners":240,"selfHostable":40,"sources":247,"stem":250,"summary":251,"website":252,"__hash__":253},"tools\u002Ftools\u002Fapplitools.yml","service","hosted-review","server-side perceptual comparison with several match levels","yml","2026-10-13","none-cloud","none",{},"Applitools Eyes",[235],"The Ultrafast Grid renders a captured DOM in many browsers and viewports server-side.","custom",[238,239],"web-app","pr",[241,242,243,244,245,246],"Selenium","Playwright","Cypress","WebdriverIO","Storybook","any (eyes-images SDK)",[248,249],"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@applitools\u002Feyes-images","https:\u002F\u002Fapplitools.com\u002Fdocs\u002Feyes\u002Fsdks\u002Fimages-js\u002Feyes","tools\u002Fapplitools","Hosted visual AI testing with SDKs for most runners and an Images SDK that accepts plain screenshots.","https:\u002F\u002Fapplitools.com","MRsX9IkRB4EEGetQnEjdJzppph2BDEJ4pGmvP_cC_sE",{"id":255,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":256,"extension":228,"hosting":153,"lastVerified":229,"license":257,"machineReadableResults":230,"manifestSupport":231,"meta":258,"name":259,"notes":260,"openSource":263,"pricingModel":264,"reviewSurface":265,"runners":266,"selfHostable":40,"sources":269,"stem":272,"summary":273,"website":274,"__hash__":275},"tools\u002Ftools\u002Fargos.yml","server-side pixel comparison with a threshold option","MIT (platform source), hosted service",{},"Argos",[261,262],"argos upload takes a directory of PNG or JPEG files, the reference branch and parallel-run options; the diff happens in the service.","The platform is open source; a documented self-hosting path was not found at the time of writing.",true,"freemium",[239,238],[242,243,245,267,244,268],"Puppeteer","any (argos upload of a folder)",[270,271],"https:\u002F\u002Fargos-ci.com\u002Fdocs\u002Fargos-cli","https:\u002F\u002Fgithub.com\u002Fargos-ci\u002Fargos","tools\u002Fargos","Hosted review service that takes screenshots uploaded from CI, compares them against the reference branch and reports on the pull request.","https:\u002F\u002Fargos-ci.com","wpdR9AMcgBtMrZ5SfQRE86WZ4e3JliUTjSCK93hN68w",{"id":277,"aliases":212,"baselineStorage":278,"category":279,"diffEngine":280,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":283,"manifestSupport":284,"meta":285,"name":286,"notes":287,"openSource":263,"pricingModel":290,"reviewSurface":291,"runners":292,"selfHostable":263,"sources":294,"stem":296,"summary":297,"website":295,"__hash__":298},"tools\u002Ftools\u002Fbackstopjs.yml","repo","runner-integration","Resemble.js, misMatchThreshold in percent","local","MIT","json-report","converter",{},"BackstopJS",[288,289],"The HTML report has an approve button that copies test bitmaps over references.","Scenarios are configured in backstop.json, not written as tests.","free",[281],[293],"Standalone (Puppeteer or Playwright engine)",[295],"https:\u002F\u002Fgithub.com\u002Fgarris\u002FBackstopJS","tools\u002Fbackstopjs","Standalone tool that screenshots a list of URLs and selectors in Puppeteer or Playwright, compares them with Resemble.js and writes HTML, JSON and JUnit reports.","oMeFX2DMKR-UGi1qOxFjX5em0G5yXt-o2TtVrd-4sI4",{"id":300,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":301,"extension":228,"hosting":153,"lastVerified":229,"license":302,"machineReadableResults":230,"manifestSupport":231,"meta":303,"name":304,"notes":305,"openSource":40,"pricingModel":264,"reviewSurface":307,"runners":308,"selfHostable":40,"sources":309,"stem":311,"summary":312,"website":313,"__hash__":314},"tools\u002Ftools\u002Fchromatic.yml","server-side, with a diff threshold per story","CLI under MIT, service proprietary",{},"Chromatic",[306],"Takes a Storybook build directory or DOM archives, not screenshots; images you captured yourself cannot be uploaded.",[239,238],[245,242,243],[310],"https:\u002F\u002Fwww.chromatic.com\u002Fdocs\u002Fcli\u002F","tools\u002Fchromatic","Hosted visual and interaction testing from the Storybook maintainers; it re-renders a Storybook build or Playwright and Cypress DOM archives in its own browsers.","https:\u002F\u002Fwww.chromatic.com","0OkDGzqoxmz--Z5zS8_m_RUoVapiXcgJEANcztDrRBU",{"id":316,"aliases":212,"baselineStorage":278,"category":279,"diffEngine":317,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":283,"manifestSupport":318,"meta":319,"name":320,"notes":321,"openSource":263,"pricingModel":290,"reviewSurface":323,"runners":324,"selfHostable":263,"sources":325,"stem":327,"summary":328,"website":326,"__hash__":329},"tools\u002Ftools\u002Fcypress-image-diff-js.yml","pixelmatch, failureThreshold as a ratio","generic",{},"cypress-image-diff-js",[322],"The JSON report lists suites and tests with baselinePath, comparisonPath, diffPath, percentage and failureThreshold.",[281],[243],[326],"https:\u002F\u002Fgithub.com\u002Fuktrade\u002Fcypress-image-diff","tools\u002Fcypress-image-diff-js","Cypress plugin that keeps baseline, comparison and diff folders and writes a JSON plus HTML report per run.","5UpPd42iu4Iqv91oKEn6OyecvfshMZBDYpRHxAFtUC8",{"id":331,"aliases":332,"baselineStorage":278,"category":279,"diffEngine":334,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":284,"meta":336,"name":337,"notes":338,"openSource":263,"pricingModel":290,"reviewSurface":340,"runners":341,"selfHostable":263,"sources":342,"stem":344,"summary":345,"website":343,"__hash__":346},"tools\u002Ftools\u002Fcypress-image-snapshot.yml",[333],"@simonsmith\u002Fcypress-image-snapshot","jest-image-snapshot (pixelmatch or SSIM)","images-only",{},"cypress-image-snapshot",[339],"Several forks exist; the maintained one at the time of writing is simonsmith\u002Fcypress-image-snapshot.",[281],[243],[343],"https:\u002F\u002Fgithub.com\u002Fsimonsmith\u002Fcypress-image-snapshot","tools\u002Fcypress-image-snapshot","Cypress port of jest-image-snapshot; same snapshot and diff-output folders, driven from cy.matchImageSnapshot.","GsenTFz1rBYWMjJXdyJk3NfAWO_LIlr3IHq7ZBRtRvA",{"id":348,"aliases":212,"baselineStorage":278,"category":279,"diffEngine":349,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":284,"meta":350,"name":351,"notes":352,"openSource":263,"pricingModel":290,"reviewSurface":354,"runners":355,"selfHostable":263,"sources":356,"stem":358,"summary":359,"website":357,"__hash__":360},"tools\u002Ftools\u002Fcypress-visual-regression.yml","pixelmatch, errorThreshold as a ratio",{},"cypress-visual-regression",[353],"The comparison result (mismatched pixels, percentage) is yielded to the test, not written to a file.",[281],[243],[357],"https:\u002F\u002Fgithub.com\u002Fcypress-visual-regression\u002Fcypress-visual-regression","tools\u002Fcypress-visual-regression","Cypress plugin with a base-generation mode and a regression mode, writing base, actual and diff images into three sibling folders.","CZWfQkSaZ8z_F5-RiuqcaV_FQOsG6yuOOOquNRWHzy8",{"id":362,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":231,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":231,"manifestSupport":231,"meta":364,"name":365,"notes":366,"openSource":263,"pricingModel":290,"reviewSurface":368,"runners":369,"selfHostable":263,"sources":371,"stem":373,"summary":374,"website":375,"__hash__":376},"tools\u002Ftools\u002Fdetox.yml","mobile-native",{},"Detox",[367],"Listed because people look for it; the docs say it does not have any sort of screenshot comparison. Pair it with a diff engine or an image-snapshot matcher.",[281],[370],"Detox (Jest)",[372],"https:\u002F\u002Fwix.github.io\u002FDetox\u002Fdocs\u002F19.x\u002Fapi\u002Fscreenshots\u002F","tools\u002Fdetox","Gray-box end-to-end testing for React Native; it can take screenshots into the artifacts folder but does not compare them.","https:\u002F\u002Fwix.github.io\u002FDetox\u002F","Fd8VgLDRzBsrJA7dYMTf2xvxK3xT0pvKyztYc7TRtaI",{"id":378,"aliases":379,"baselineStorage":278,"category":363,"diffEngine":381,"extension":228,"hosting":281,"lastVerified":229,"license":382,"machineReadableResults":335,"manifestSupport":318,"meta":383,"name":384,"notes":385,"openSource":263,"pricingModel":290,"reviewSurface":388,"runners":389,"selfHostable":263,"sources":391,"stem":393,"summary":394,"website":395,"__hash__":396},"tools\u002Ftools\u002Fflutter-golden.yml",[380],"matchesGoldenFile","exact pixel comparison by default; the comparator is pluggable","BSD-3-Clause",{},"Flutter golden tests",[386,387],"A failure writes _masterImage, _testImage, _isolatedDiff and _maskedDiff images next to the golden under a failures folder.","Rendering differs between platforms, so goldens are usually generated on one OS, often in CI.",[281],[390],"flutter test",[392],"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_test\u002Flib\u002Fsrc\u002F_goldens_io.dart","tools\u002Fflutter-golden","Flutter's built-in matchesGoldenFile matcher compares a widget's rendering against a golden PNG in the repository.","https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fflutter_test\u002FmatchesGoldenFile.html","jbXbvr_aexwD7rG_DKgNQ-QKKfW7nNWOHrV7OioRtSQ",{"id":398,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":399,"extension":228,"hosting":153,"lastVerified":229,"license":212,"machineReadableResults":230,"manifestSupport":231,"meta":400,"name":401,"notes":402,"openSource":40,"pricingModel":404,"reviewSurface":405,"runners":406,"selfHostable":263,"sources":408,"stem":412,"summary":413,"website":414,"__hash__":415},"tools\u002Ftools\u002Fhappo.yml","server-side",{},"Happo",[403],"An on-premise bundle is sold for teams that need to keep images inside their network.","per-screenshot",[239,238],[245,242,243,267,407],"any (image API)",[409,410,411],"https:\u002F\u002Fhappo.io\u002Fdocs\u002Fapi","https:\u002F\u002Fdocs.happo.io\u002Fdocs\u002Fimage-api","https:\u002F\u002Fhappo.io\u002Fblog\u002Ftotal-control-and-security-with-happo-on-premise-solutions","tools\u002Fhappo","Hosted cross-browser screenshot review with a REST API that accepts images by hash and compares reports by commit.","https:\u002F\u002Fhappo.io","K95Nxa_34EL_CAKaqfmfyXohe3RmGXI8XEYe_PEz7GI",{"id":417,"aliases":418,"baselineStorage":278,"category":279,"diffEngine":420,"extension":228,"hosting":281,"lastVerified":229,"license":421,"machineReadableResults":335,"manifestSupport":284,"meta":422,"name":423,"notes":424,"openSource":263,"pricingModel":290,"reviewSurface":426,"runners":427,"selfHostable":263,"sources":430,"stem":432,"summary":433,"website":431,"__hash__":434},"tools\u002Ftools\u002Fjest-image-snapshot.yml",[419],"toMatchImageSnapshot","pixelmatch or SSIM (comparisonMethod), failureThreshold in pixels or percent","Apache-2.0",{},"jest-image-snapshot",[425],"The diff image is a baseline | diff | received composite unless onlyDiff is set; the received image is stored separately only with storeReceivedOnFailure.",[281],[428,429],"Jest","Puppeteer, Playwright or anything that yields a PNG buffer",[431],"https:\u002F\u002Fgithub.com\u002Famericanexpress\u002Fjest-image-snapshot","tools\u002Fjest-image-snapshot","Jest matcher that compares a PNG buffer against a stored snapshot and writes a composite diff image on failure.","UuvG4Mc4wgtbot7S-Ty-lqH72_Kclt08d3rX0SZqYL0",{"id":436,"aliases":212,"baselineStorage":278,"category":279,"diffEngine":437,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":318,"meta":438,"name":439,"notes":440,"openSource":263,"pricingModel":290,"reviewSurface":442,"runners":443,"selfHostable":263,"sources":444,"stem":446,"summary":447,"website":445,"__hash__":448},"tools\u002Ftools\u002Floki.yml","pixelmatch or looks-same, configurable per target",{},"Loki",[441],"Writes .loki\u002Freference, .loki\u002Fcurrent and .loki\u002Fdifference folders; no machine-readable summary was found.",[281],[245],[445],"https:\u002F\u002Fgithub.com\u002Foblador\u002Floki","tools\u002Floki","Visual regression for Storybook stories, rendered in Chrome (local, Docker or AWS Lambda) or iOS and Android simulators.","eK0TX1MNYelig3dlEZt_JiIcgAk998pFp-HolZDJAqk",{"id":450,"aliases":212,"baselineStorage":278,"category":451,"diffEngine":452,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":231,"manifestSupport":231,"meta":453,"name":454,"notes":455,"openSource":263,"pricingModel":290,"reviewSurface":457,"runners":458,"selfHostable":263,"sources":460,"stem":462,"summary":463,"website":461,"__hash__":464},"tools\u002Ftools\u002Flooks-same.yml","diff-engine","CIEDE2000 colour difference with tolerance, anti-aliasing and ignore-caret options",{},"looks-same",[456],"Returns equality and the diff bounds and clusters; can build a diff image with configurable highlight colour.",[281],[459],"any (library)",[461],"https:\u002F\u002Fgithub.com\u002Fgemini-testing\u002Flooks-same","tools\u002Flooks-same","Image comparison library with CIEDE2000 colour difference, anti-aliasing and caret tolerance, from the Gemini and Testplane authors.","P7y1sQgkuAy9DsxlY1wrTo_4yRSWRDtijHme2C74VMA",{"id":466,"aliases":212,"baselineStorage":467,"category":226,"diffEngine":468,"extension":228,"hosting":469,"lastVerified":229,"license":470,"machineReadableResults":335,"manifestSupport":318,"meta":471,"name":472,"notes":473,"openSource":263,"pricingModel":264,"reviewSurface":475,"runners":476,"selfHostable":263,"sources":481,"stem":484,"summary":485,"website":486,"__hash__":487},"tools\u002Ftools\u002Flost-pixel.yml","repo-or-service","pixelmatch or odiff","local-or-cloud","MIT (engine), platform proprietary",{},"Lost Pixel",[474],"The engine writes .lostpixel\u002Fbaseline, current and difference folders; no JSON summary was found.",[281,239,238],[245,477,478,479,480],"Ladle","Histoire","page list","any (customShots folder)",[482,483],"https:\u002F\u002Fdocs.lost-pixel.com\u002Fuser-docs\u002Fapi-reference\u002Flost-pixel.config.js-or-ts.md","https:\u002F\u002Fgithub.com\u002Flost-pixel\u002Flost-pixel","tools\u002Flost-pixel","Open-source engine that screenshots Storybook, Ladle, Histoire or a list of pages and diffs locally, with an optional hosted platform for review.","https:\u002F\u002Flost-pixel.com","_xVT_0YtJHlw4cKt_2KBQuQThBhAkxLnK_j6Lz1RBG4",{"id":489,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":490,"extension":228,"hosting":469,"lastVerified":229,"license":421,"machineReadableResults":335,"manifestSupport":318,"meta":491,"name":492,"notes":493,"openSource":263,"pricingModel":264,"reviewSurface":495,"runners":496,"selfHostable":263,"sources":498,"stem":500,"summary":501,"website":502,"__hash__":503},"tools\u002Ftools\u002Fmaestro.yml","pixel comparison with a threshold",{},"Maestro",[494],"Diff images land in ~\u002F.maestro\u002Ftests\u002F\u003Ctimestamp>\u002F\u003Cflow>\u002F as step-NNN-assertScreenshot-diff.png.",[281,238],[497],"Maestro flows (iOS, Android, web)",[499],"https:\u002F\u002Fdocs.maestro.dev\u002Freference\u002Fcommands-available\u002Fassertscreenshot","tools\u002Fmaestro","Mobile UI testing framework with an assertScreenshot command that compares against a baseline and writes a diff image into the run's artifacts.","https:\u002F\u002Fdocs.maestro.dev","UJR7IJ0McM97wetCXS2G-dohIXtSFkjvtNx0czi4QTU",{"id":505,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":506,"extension":228,"hosting":153,"lastVerified":229,"license":212,"machineReadableResults":230,"manifestSupport":231,"meta":507,"name":508,"notes":509,"openSource":40,"pricingModel":236,"reviewSurface":511,"runners":512,"selfHostable":40,"sources":514,"stem":516,"summary":517,"website":518,"__hash__":519},"tools\u002Ftools\u002Fmeticulous.yml","server-side replay and comparison",{},"Meticulous",[510],"Nothing to convert or upload; the approach is a different one from screenshot assertions.",[239,238],[513],"none (session recording)",[515],"https:\u002F\u002Fwww.meticulous.ai\u002Fhow-it-works","tools\u002Fmeticulous","Records user sessions through a script tag and replays them against new builds in the cloud, diffing the result; no screenshots are taken by the team.","https:\u002F\u002Fwww.meticulous.ai","QDBlHYqGhrzN9uOjaoLGvs-riKnUUC2UR91lFvCv2EQ",{"id":521,"aliases":212,"baselineStorage":278,"category":451,"diffEngine":522,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":231,"manifestSupport":231,"meta":523,"name":524,"notes":525,"openSource":263,"pricingModel":290,"reviewSurface":527,"runners":528,"selfHostable":263,"sources":530,"stem":532,"summary":533,"website":531,"__hash__":534},"tools\u002Ftools\u002Fodiff.yml","per-pixel YIQ colour distance with a threshold, anti-aliasing and ignore regions",{},"odiff",[526],"The CLI exit code and output report the number of differing pixels and the percentage.",[281],[529],"any (CLI or library)",[531],"https:\u002F\u002Fgithub.com\u002FdmtrKovalenko\u002Fodiff","tools\u002Fodiff","Fast native image comparison with a CLI and Node bindings, used by Lost Pixel and others where pixelmatch is too slow.","5sSExLAhyMkVKUWTIHsxfSndUagnxXdcEHjDrvutS70",{"id":536,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":537,"extension":228,"hosting":281,"lastVerified":229,"license":421,"machineReadableResults":335,"manifestSupport":318,"meta":538,"name":539,"notes":540,"openSource":263,"pricingModel":290,"reviewSurface":542,"runners":543,"selfHostable":263,"sources":545,"stem":547,"summary":548,"website":546,"__hash__":549},"tools\u002Ftools\u002Fpaparazzi.yml","pixel comparison with a configurable max percent difference",{},"Paparazzi",[541],"Failures write delta images under build\u002Fpaparazzi\u002Ffailures and an HTML report; no JSON summary was found.",[281],[544],"JUnit (Android layouts and Compose)",[546],"https:\u002F\u002Fgithub.com\u002Fcashapp\u002Fpaparazzi","tools\u002Fpaparazzi","Renders Android layouts on the JVM without a device or emulator and verifies them against golden images in the repository.","AD8UC1fNp4BYEIHU7qOMxI8L20HF6etC2r3gDYMeDpI",{"id":551,"aliases":552,"baselineStorage":225,"category":226,"diffEngine":554,"extension":228,"hosting":153,"lastVerified":229,"license":302,"machineReadableResults":230,"manifestSupport":231,"meta":555,"name":556,"notes":557,"openSource":40,"pricingModel":264,"reviewSurface":559,"runners":560,"selfHostable":40,"sources":562,"stem":565,"summary":566,"website":567,"__hash__":568},"tools\u002Ftools\u002Fpercy.yml",[553],"BrowserStack Percy","server-side, with a configurable diff sensitivity",{},"Percy",[558],"DOM snapshots are re-rendered in Percy's browsers, so cross-browser results come without running the tests again.",[239,238],[243,242,267,241,245,561],"any (percy upload of a folder)",[563,564],"https:\u002F\u002Fwww.browserstack.com\u002Fdocs\u002Fpercy\u002Freferences\u002Fcommands","https:\u002F\u002Fgithub.com\u002Fpercy\u002Fcli","tools\u002Fpercy","BrowserStack's hosted visual testing; SDKs capture DOM snapshots that are rendered in the service, and percy upload takes plain images.","https:\u002F\u002Fwww.browserstack.com\u002Fpercy","wIqhSk49bxFFX07Gmzxa7qC8MOjPXYNj8rgSFlSLpv8",{"id":570,"aliases":212,"baselineStorage":278,"category":451,"diffEngine":571,"extension":228,"hosting":281,"lastVerified":229,"license":572,"machineReadableResults":231,"manifestSupport":231,"meta":573,"name":574,"notes":575,"openSource":263,"pricingModel":290,"reviewSurface":577,"runners":578,"selfHostable":263,"sources":579,"stem":581,"summary":582,"website":580,"__hash__":583},"tools\u002Ftools\u002Fpixelmatch.yml","per-pixel YIQ colour distance with a threshold, anti-aliased pixels ignored by default","ISC",{},"pixelmatch",[576],"Returns the number of differing pixels and writes a diff image; everything else is up to the caller.",[281],[459],[580],"https:\u002F\u002Fgithub.com\u002Fmapbox\u002Fpixelmatch","tools\u002Fpixelmatch","Small pixel-level image comparison library with anti-aliasing detection; the engine behind Playwright, Vitest, jest-image-snapshot and many plugins.","pzBeBawf9c-eqaPcV_SLf8DFGMy3IQ7jgcD-92X6Uqk",{"id":585,"aliases":586,"baselineStorage":278,"category":279,"diffEngine":589,"extension":228,"hosting":469,"lastVerified":229,"license":282,"machineReadableResults":117,"manifestSupport":590,"meta":591,"name":592,"notes":593,"openSource":263,"pricingModel":264,"reviewSurface":596,"runners":597,"selfHostable":263,"sources":599,"stem":602,"summary":603,"website":600,"__hash__":604},"tools\u002Ftools\u002Fpixsame.yml",[587,588],"@pixsame\u002Fcypress-plugin-visual-regression-diff","@frsource\u002Fcypress-plugin-visual-regression-diff","pixelmatch-style pixel comparison with a configurable threshold; pinned Docker renderer optional","native",{},"pixsame",[594,595],"Maintained by the same team that runs this site; the comparison is written to be fair, not flattering.","The GitHub App for approving baselines from a pull request and the hosted platform are announced, not released.",[281,239],[243,598],"Playwright (in preparation)",[600,601],"https:\u002F\u002Fpixsame.com","https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@pixsame\u002Fcypress-plugin-visual-regression-diff","tools\u002Fpixsame","Cypress plugin (Playwright in preparation) that compares screenshots in the runner, shows the diff in the Cypress UI, and writes the run manifest for review tooling.","08yzM5azyn8c3E-XTJGhN00Dw_s1sgA76MTHq0tg8xE",{"id":606,"aliases":607,"baselineStorage":278,"category":279,"diffEngine":609,"extension":228,"hosting":281,"lastVerified":229,"license":421,"machineReadableResults":283,"manifestSupport":284,"meta":610,"name":611,"notes":612,"openSource":263,"pricingModel":290,"reviewSurface":615,"runners":616,"selfHostable":263,"sources":617,"stem":620,"summary":621,"website":618,"__hash__":622},"tools\u002Ftools\u002Fplaywright.yml",[608],"@playwright\u002Ftest","pixelmatch (threshold, maxDiffPixels, maxDiffPixelRatio); ssim-cie94 comparator optional",{},"Playwright toHaveScreenshot",[613,614],"The JSON reporter lists the images as attachments named \u003Cname>-expected, -actual and -diff; a passing comparison leaves no trace.","The HTML report shows the three images with a slider.",[281],[242],[618,619],"https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Ftest-snapshots","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fapi\u002Fclass-testresult","tools\u002Fplaywright","Built-in screenshot assertion of Playwright Test; references live next to the tests, failures leave expected, actual and diff images in test-results.","2VHO8iaQY-GOkh6JLMfHBZjmdLfHw3OKVQ6F0O-oL_I",{"id":624,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":625,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":318,"meta":626,"name":627,"notes":628,"openSource":263,"pricingModel":290,"reviewSurface":630,"runners":631,"selfHostable":263,"sources":633,"stem":635,"summary":636,"website":634,"__hash__":637},"tools\u002Ftools\u002Freact-native-owl.yml","pixel comparison",{},"React Native Owl",[629],"The documentation site was unreachable when this entry was checked; details come from the repository README.",[281],[632],"React Native (Jest)",[634],"https:\u002F\u002Fgithub.com\u002FFormidableLabs\u002Freact-native-owl","tools\u002Freact-native-owl","Visual regression for React Native apps on iOS and Android simulators, with baseline, latest and diff folders and an HTML report.","wTUG3gPGz-nqPmjoFE5suJm8xiIvnXny3KCt8OcV1E4",{"id":639,"aliases":640,"baselineStorage":225,"category":226,"diffEngine":643,"extension":228,"hosting":157,"lastVerified":229,"license":282,"machineReadableResults":283,"manifestSupport":318,"meta":644,"name":645,"notes":646,"openSource":263,"pricingModel":290,"reviewSurface":649,"runners":650,"selfHostable":263,"sources":652,"stem":655,"summary":656,"website":653,"__hash__":657},"tools\u002Ftools\u002Freg-suit.yml",[641,642],"reg-cli","reg-viz","reg-cli (pixel comparison with a threshold, anti-aliasing tolerance)",{},"reg-suit",[647,648],"reg.json lists failed, new, deleted and passed items by file name, without ratios.","Self-hosted on your own object storage; the notifier plugins post to GitHub, GitLab, Slack and Chatwork.",[239,238],[651],"any (takes a directory of images)",[653,654],"https:\u002F\u002Fgithub.com\u002Freg-viz\u002Freg-suit","https:\u002F\u002Fgithub.com\u002Freg-viz\u002Freg-cli","tools\u002Freg-suit","Compares a directory of actual images against expected ones fetched from S3 or GCS, publishes an HTML report and comments on the pull request; reg-cli is the engine on its own.","f5OyBtVGXF1eErNTbwjKtZjUm76NrgIZ-yvwzRXph8c",{"id":659,"aliases":212,"baselineStorage":278,"category":451,"diffEngine":660,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":231,"manifestSupport":231,"meta":661,"name":662,"notes":663,"openSource":263,"pricingModel":290,"reviewSurface":665,"runners":666,"selfHostable":263,"sources":668,"stem":670,"summary":671,"website":669,"__hash__":672},"tools\u002Ftools\u002Fresemblejs.yml","per-pixel colour tolerance with ignore modes (antialiasing, colors, alpha, nothing)",{},"Resemble.js",[664],"Reports misMatchPercentage as a string with two decimals, dimension differences and analysis time.",[281],[667],"any (library, browser or Node)",[669],"https:\u002F\u002Fgithub.com\u002Frsmbl\u002FResemble.js","tools\u002Fresemblejs","Image analysis and comparison library that reports a mismatch percentage and renders highlighted diffs; the engine behind BackstopJS.","1u87nIQsc4_IDoRYwc1BkqXuq1rUyihzyKK-6W_zYgw",{"id":674,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":675,"extension":228,"hosting":281,"lastVerified":229,"license":421,"machineReadableResults":283,"manifestSupport":284,"meta":676,"name":677,"notes":678,"openSource":263,"pricingModel":290,"reviewSurface":681,"runners":682,"selfHostable":263,"sources":684,"stem":686,"summary":687,"website":685,"__hash__":688},"tools\u002Ftools\u002Froborazzi.yml","pixel comparison with changeThreshold and a pluggable comparator",{},"Roborazzi",[679,680],"build\u002Ftest-results\u002Froborazzi\u002F\u003Cvariant>\u002Fresults-summary.json lists every capture as recorded, added, changed or unchanged with its diff percentage and file paths.","Compare writes a golden | diff | actual composite named _compare.png.",[281],[683],"JUnit with Robolectric (Android, Compose and Views)",[685],"https:\u002F\u002Fgithub.com\u002Ftakahirom\u002Froborazzi","tools\u002Froborazzi","Android screenshot tests that run under Robolectric on the JVM, with record, compare and verify Gradle tasks and a JSON results summary.","tcKuXoX0xokv-ZfFSKq4dM_s-lCBXJpm0xhhhmV6FRc",{"id":690,"aliases":691,"baselineStorage":225,"category":226,"diffEngine":399,"extension":228,"hosting":153,"lastVerified":229,"license":212,"machineReadableResults":230,"manifestSupport":231,"meta":693,"name":694,"notes":212,"openSource":40,"pricingModel":236,"reviewSurface":695,"runners":696,"selfHostable":40,"sources":698,"stem":700,"summary":701,"website":702,"__hash__":703},"tools\u002Ftools\u002Fsauce-visual.yml",[692],"Screener",{},"Sauce Visual",[238,239],[241,242,243,244,245,697],"any (GraphQL API)",[699],"https:\u002F\u002Fdocs.saucelabs.com\u002Fvisual-testing\u002Fworkflows\u002Fapi-lifecycle\u002F","tools\u002Fsauce-visual","Sauce Labs' hosted visual testing; SDKs or a GraphQL API create a build, upload PNG snapshots and finish the build for review.","https:\u002F\u002Fdocs.saucelabs.com\u002Fvisual-testing\u002F","If4vd6AeVxckFs_iWfN_74So406ge9UwgPuHGKHVum0",{"id":705,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":706,"extension":228,"hosting":281,"lastVerified":229,"license":421,"machineReadableResults":335,"manifestSupport":318,"meta":707,"name":708,"notes":709,"openSource":263,"pricingModel":290,"reviewSurface":711,"runners":712,"selfHostable":263,"sources":714,"stem":716,"summary":717,"website":715,"__hash__":718},"tools\u002Ftools\u002Fshot.yml","pixel comparison with a tolerance",{},"Shot",[710],"A metadata.json accompanies the screenshots; its shape was not verified for this comparison.",[281],[713],"Android instrumentation tests",[715],"https:\u002F\u002Fgithub.com\u002Fpedrovgs\u002FShot","tools\u002Fshot","Gradle plugin that records and verifies Android screenshots on a device or emulator and builds an HTML verification report.","3cIcun4F4rGXas_n1BIcJot94jDav2T3tO2KkilNK0A",{"id":720,"aliases":212,"baselineStorage":278,"category":363,"diffEngine":721,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":318,"meta":722,"name":723,"notes":724,"openSource":263,"pricingModel":290,"reviewSurface":726,"runners":728,"selfHostable":263,"sources":731,"stem":733,"summary":734,"website":732,"__hash__":735},"tools\u002Ftools\u002Fswift-snapshot-testing.yml","pixel comparison with precision and perceptualPrecision options",{},"swift-snapshot-testing",[725],"Failures attach reference, failure and difference images to the XCTest result; reading them back means parsing an xcresult bundle.",[281,727],"ide",[729,730],"XCTest","Swift Testing",[732],"https:\u002F\u002Fgithub.com\u002Fpointfreeco\u002Fswift-snapshot-testing","tools\u002Fswift-snapshot-testing","Snapshot testing for Swift with image strategies for views, view controllers and SwiftUI, storing references in __Snapshots__ next to the tests.","E1bJi1OCMacEo7pN9wdM6NB2IoVM_Qip_OvbzpCg0p8",{"id":737,"aliases":738,"baselineStorage":278,"category":279,"diffEngine":740,"extension":228,"hosting":281,"lastVerified":229,"license":282,"machineReadableResults":335,"manifestSupport":284,"meta":741,"name":742,"notes":743,"openSource":263,"pricingModel":290,"reviewSurface":745,"runners":746,"selfHostable":263,"sources":748,"stem":751,"summary":752,"website":749,"__hash__":753},"tools\u002Ftools\u002Fvitest.yml",[739],"vitest browser mode","pixelmatch (threshold, allowedMismatchedPixelRatio)",{},"Vitest toMatchScreenshot",[744],"File names carry the browser and platform (button-chromium-darwin.png), so one test keeps one reference per browser and OS.",[281],[747],"Vitest (browser mode)",[749,750],"https:\u002F\u002Fvitest.dev\u002Fguide\u002Fbrowser\u002Fvisual-regression-testing","https:\u002F\u002Fvitest.dev\u002Fblog\u002Fvitest-4","tools\u002Fvitest","Screenshot assertion of Vitest browser mode; references in __screenshots__ next to the tests, failures under .vitest\u002Fattachments.","sl4CwZUHQwCUh3L7d4bWYCnYd-A9km67vARh8R2BTdg",{"id":755,"aliases":212,"baselineStorage":225,"category":226,"diffEngine":756,"extension":228,"hosting":469,"lastVerified":229,"license":302,"machineReadableResults":283,"manifestSupport":318,"meta":757,"name":758,"notes":759,"openSource":40,"pricingModel":264,"reviewSurface":761,"runners":762,"selfHostable":40,"sources":764,"stem":767,"summary":768,"website":769,"__hash__":770},"tools\u002Ftools\u002Fvizzly.yml","server-side, with a threshold option; local comparison in TDD mode",{},"Vizzly",[760],"TDD mode writes a .vizzly folder with screenshots and diffs and can print JSON context.",[281,239,238],[242,243,267,241,763],"any (vizzly upload of a folder)",[765,766],"https:\u002F\u002Fdocs.vizzly.dev\u002Fintegration\u002Fcli\u002Fupload","https:\u002F\u002Fgithub.com\u002Fvizzly-testing\u002Fcli","tools\u002Fvizzly","Hosted review service with a CLI that uploads a folder of screenshots and a local TDD mode that diffs on the developer's machine.","https:\u002F\u002Fvizzly.dev","mGgHqLfgo0lFJr9R4fIISX02dvKTXCvJUUEkjOWElvw",1791993875092]