Skip to content
Latchkey

jest-image-snapshot CI vs local rendering mismatch in CI

Image snapshots that pass on a developer laptop can fail in CI because the two environments render differently: different OS font stacks, a different Chromium build, or a different device scale. The fix is to make baselines in the same container CI runs.

What this error means

Snapshots pass on macOS or Windows locally but fail in Linux CI. The diff shows fringing around all text and gradients rather than a discrete layout change, indicating an environment difference, not a code change.

jest-image-snapshot
  # local: passes
  # CI (linux container):
  Expected image to match or be a close match to snapshot but was 2.87% different from snapshot

Common causes

Different OS and font rendering than the runner

The baseline was generated on macOS or Windows, but CI renders on Linux with different font hinting and anti-aliasing, so every glyph differs slightly.

A different Chromium/Puppeteer build

Local and CI use different browser versions, which can change how sub-pixel rendering and gradients are drawn.

How to fix it

Generate baselines inside the CI image

  1. Run the snapshot update inside the same Docker image CI uses (for example a Puppeteer image).
  2. Commit the regenerated __image_snapshots__.
  3. Re-run CI so it compares against baselines made in the identical environment.
Terminal
docker run --rm -v $(pwd):/app -w /app \
  ghcr.io/puppeteer/puppeteer:latest \
  npx jest --ci --updateSnapshot

Pin fonts and browser version

Bundle the required fonts into the image and pin the browser version so local and CI rendering stay identical.

Dockerfile
RUN apt-get update && apt-get install -y fonts-liberation fonts-noto-color-emoji

How to prevent it

  • Always generate baselines in the same container CI uses.
  • Pin the browser version across local and CI.
  • Install the exact fonts the pages need into the image.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →