Pixelmatch Tuning Recipes
When to Use
Use this as the scenario-by-scenario reference for picking a
thresholdvalue.
Decision
| Scenario | threshold |
Notes |
|---|---|---|
| Pixel-perfect, same OS, same browser version | 0.1 (library default) |
Catches real regressions; rare false positives |
| Same OS, anti-aliasing variability (Canvas/WebGL) | 0.1 with includeAA: false (default) |
AA detector handles most of it |
| Cross-OS (mac vs Linux CI) | 0.2–0.3 |
Combine with maxDiffPixelRatio: 0.01 to absorb noise |
| Different font hinting / sub-pixel rendering across OSes | 0.3+, or switch to looks-same / dssim |
Pixelmatch's YIQ saturates here; perceptual SSIM is more stable |
| Animations, gradients, video frames | Use maxDiffPixels / maxDiffPixelRatio rather than raising threshold |
Keeps regression sensitivity high while tolerating bounded noise |
Pattern: incremental tightening
Start with Playwright's defaults (threshold: 0.2, no maxDiffPixels). When tests are stable, tighten:
- Lower
thresholdto0.15, then0.1 - Add a small
maxDiffPixelRatio: 0.005ceiling - For sub-pixel-precise components, override per-test with
threshold: 0.05and a comment
If tightening produces flakes, the env or stability controls (animations, fonts) are the real problem. Don't bandaid with looser thresholds.
Common Mistakes
- Wrong: Setting
threshold: 0.5+as the default — effectively not testing - Wrong: Per-test thresholds without a
// whycomment — six months later the comment is the only justification - Wrong: Tightening on day one — start lax, stabilize, then tighten
See Also
- Inside Playwright —
maxDiffPixelsandmaxDiffPixelRatioexplained - Threshold — what the threshold value means mechanically
- Limitations & Alternatives — when to switch algorithms entirely
- Reference: mapbox/pixelmatch
- Reference: odiff (faster alternative)