
Version-Controlling Screenshot Baselines Alongside Your Codebase

Snapshot Site Team
22 Apr 2025 - 03 Mins read
Every visual-diff workflow covered so far — CI regression checks, uptime monitoring, component-level audits — depends on a stored baseline image that's assumed to represent "the correct state." What none of those posts covers is what happens to that baseline over time: who updates it, when, and how it stays in sync with the code that produced it in the first place. Get that wrong, and every diff check quietly degrades into comparing against a baseline nobody trusts anymore.
The Core Problem: Baselines Drift From Reality
A baseline captured once and left alone becomes wrong the moment the page legitimately changes on purpose. If updating it is a manual, easy-to-forget step, one of two things happens: either the diff check starts failing on every legitimate change (and gets ignored or disabled), or someone updates the baseline without real scrutiny just to make the noise stop (and a real regression slips through in that same update). Neither is a technical problem — it's a process problem, and it needs a process fix.
Pattern: Baselines Live in the Same Pull Request as the Change
The most reliable fix is treating a baseline update the same way you'd treat any other generated artifact that needs to stay in sync with code: require it to be updated in the same pull request as the change that invalidates it, and require a human to actually look at the new baseline before approving.
A practical CI step:
# In the same PR that changes the pricing page's layout:
curl --request POST \
--url https://api.prod.ss.snapshot-site.com/api/v1/screenshot \
--header 'Content-Type: application/json' \
--header 'x-snapshotsiteapi-key: YOUR_API_KEY' \
--data '{
"url": "https://preview.example.com/pricing",
"format": "png",
"width": 1440,
"fullSize": true,
"hideCookie": true
}' | jq -r '.link' > new-baseline-url.txt
# Download and commit the new baseline image alongside the code change
curl -o baselines/pricing.png "$(cat new-baseline-url.txt)"
Committing the resulting PNG (or a pointer to it) into the same commit as the layout change means the baseline's history lives in git, reviewable in the same diff as everything else, rather than as an invisible side effect of running a script separately.
Where to Actually Store the Images
Raw PNGs don't belong in a normal git history at scale — they bloat the repository fast. Git LFS is a reasonable fit if the team already uses it for other binary assets. The more common pattern at scale is storing images in object storage (an S3-style bucket) and committing only a small manifest file — a JSON or YAML mapping of page name to image URL and a content hash — so the manifest's diff in a pull request still shows exactly which baselines changed, without the repository absorbing the image bytes directly.
Reviewing a Baseline Update Like Any Other Change
The habit worth building is treating "this PR updates a baseline" as a signal that gets the same scrutiny as any other change to shared, load-bearing state — not a checkbox to click through quickly because it's "just an image." A short comment in the PR explaining why the baseline changed (which section moved, and why that's expected) turns a silent binary diff into something a reviewer can actually evaluate.
Rotating Out Baselines That No Longer Matter
A page that gets redesigned entirely, or retired, should have its baseline removed from the manifest deliberately, not left behind as dead weight that a future audit has to figure out is safe to delete. Treating baseline removal as its own small, intentional step avoids a slow accumulation of stale images nobody remembers the purpose of.
Getting the baseline lifecycle right is what makes every other visual-diff workflow in this series actually trustworthy over time, and Snapshot Site is the same one-call capture either way — the discipline is entirely in how your team manages what gets stored.

