visual-diff
Skill4 starsChanged 17 days agoMITView on GitHub
Objectively measure how far a rendered output (PDF, page, image) deviates from a visual reference, with a cell grid, mean error per cell, pre-blur against antialiasing, zones with semantic names and overlays that reveal misalignment. Use when an official design exists to compare against, when you want a ranking of which zones are worst, or as a safety net after a batch of layout changes that eyeball review doesn't cover.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- NicholasFlemmer/styx-apptheir own version, first seen Oct 9, 2026
- aditya-deokar/software-factorytheir own version, first seen Sep 29, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- NicholasFlemmer/styx-app★ 31same name
- aditya-deokar/software-factory★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository46 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-repo-to-docsSkill
- adrSkill
- auth-bypass-localSkill
- before-afterSkill
- bug-huntSkill
- carry-envSkill
- code-healthSkill
- crux-doctorSkill
- crux-initSkill
- css-to-componentsSkill
- deploy-fallbackSkill
- deploy-watchSkill
- device-loopSkill
- drive-browserSkill
- e2eSkill
- end-sessionSkill
- eval-fixturesSkill
- explain-planSkill
- flowSkill
- grillSkill
- merge-conflictsSkill
- motion-videoSkill
- oauth-reauthorizeSkill
- prod-signalsSkill
- promote-to-docsSkill
- prose-checkSkill
- read-documentSkill
- render-loopSkill
- repo-mapSkill
- review-prSkill
- root-causeSkill
- runbookSkill
- security-auditSkill
- share-localSkill
- shipSkill
- skill-auditSkill
- skill-creatorSkill
- teachSkill
- ui-behaviourSkill
- ui-tellsSkill
- visual-testSkill
- wizardSkill
- workspaceSkill
- write-testsSkill
- x-postsSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 68
Fix the data before comparing: If the current render carries different data from the reference, you are measuring content and not design, …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
visual-diff
It answers one specific question: how far am I from the reference, and where.
It is the measurable half of visual work; the other half, when there is no
reference and the criterion is a person's, is /render-loop.
When to use each
| Situation | Tool |
| There is an official design to compare against | this one |
| Before accepting a batch of changes | this one |
| Subjective notes: "bigger", "more air" | /render-loop |
| Confirming a change is noticeable | /render-loop |
Usage
python3 <this-skill-directory>/scripts/imgdiff.py <current> <reference> \
--out diff-out --grid 12x18 --blocks blocks.jsonIt accepts PDFs (rasterized with pdftoppm) or images. It produces report.md
sorted by descending deviation, scores.json and one overlay per page. It exits
with code 1 if any cell exceeds the threshold, so it works directly as a gate in
a hook or in CI.
It requires python3 with numpy and Pillow, and poppler for PDFs.
How it works, and why
- Rasterize both outputs at the same resolution and fit the current one to the reference's size.
- Apply a pre-blur. This is what makes comparison between different renderers usable: without it, antialiasing dominates the signal and everything looks different. With it, the real defects of position, size and colour survive.
- Split into a grid and compute the mean absolute error per cell. One number per page says nothing actionable; per cell, it does.
- Ignore cells that are almost white in both. They are the margins: without this filter they inflate the average and hide the real defects.
- Label each cell with its semantic block. A report saying "the header is shifted" is actionable; one saying "cell 3,7" forces you to go look at the PNG to understand what is happening.
- Generate the overlay. What matches comes out grey; misalignment shows up as a coloured ghost, blue where there is content only in the current one and warm where there is only in the reference.
The semantic blocks
A JSON with the zones in normalized 0 to 1 coordinates, optionally per page:
[{"name": "header", "page": 1, "box": [0, 0, 1, 0.2]},
{"name": "left-card", "page": 1, "box": [0, 0.28, 0.55, 0.52]}]It is worth writing once: it turns the report from a list of coordinates into a list of names where you already know where to make the change.
The rule that decides whether the measurement is worth anything
Fix the data before comparing. If the current render carries different data from the reference, you are measuring content and not design, and any real difference gets buried under the noise.
The normal thing is to expose a mode in the application itself that fills the output with the same data as the reference. Without that, the diff is inconclusive and shouldn't be interpreted.
Systematic coverage
A comparison against a reference measures the case you have rendered. If the output has fixed-size canvases (typical in reports and documents), content that doesn't fit is clipped silently, and eyeball review only detects what one thinks to look at.
That is why it is worth accompanying it with a battery of scenarios that renders the edge cases: the longest possible text, extreme values, empty fields, all the variants of a label. It is the part that must be run without fail after touching typography or spacing.
Documented false positive
If artifacts appear (black headers, badly composed blocks) in some viewers and not in others, suspect the renderer before the design. The usual cause is launching the headless browser without the same flags the production pipeline uses.
Any comparison script must replicate exactly those flags. This cost one team a whole working day before it was documented.
Related
/render-loop: iterate when there is no reference and the criterion is subjective/visual-test: inspect web pages across viewports
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

