Agent skill

Visual Diff

by bitovi in bitovi/ai-enablement-prompts

Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML…

MITAuto-check passedFrontend & Design

Install Visual Diff

skills CLI
$ npx skills add bitovi/ai-enablement-prompts --skill visual-diff -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install bitovi/ai-enablement-prompts visual-diff --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/bitovi/ai-enablement-prompts.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/playwright/skills/visual-diff .claude/skills/visual-diff && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
visual-diff
GitHub stars
121
Token cost
~2.9k tokens
SKILL.md length
994 words
Files
1
Skills in repo
40
Repo updated
First seen
Licence
MIT

At a glance

Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML…

  • Works in 7 steps: Receive inputs → Screenshot the baseline → Screenshot the current → …
  • Replicating an existing page
  • SKILL.md covers When to Use, When NOT to Use, Prerequisites and Workflow, plus 5 more sections
  • Calls node and npx; reaches bitovi.com

What it does

Visual Diff is an agent skill from bitovi/ai-enablement-prompts. Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML corrections. Use when replicating an existing page or component, verifying visual accuracy, or checking responsive fidelity.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering Visual regression testing, Responsive design and Browser testing. It works with Storybook and Playwright. The repository describes itself as: Prompts Bitovi uses for software development. The licence is MIT.

When your agent uses it

  • Replicating an existing page
  • Verifying visual accuracy
  • Checking responsive fidelity

Example prompts

  • “/visual-diff”

Requirements

  • Node.js

Workflow steps

7 steps, taken from the step headings in SKILL.md.

  1. Receive inputs
  2. Screenshot the baseline
  3. Screenshot the current
  4. Run the diff script
  5. View the diff image
  6. Interpret and act
  7. Fix and re-diff

What it can do on your machine

Read from SKILL.md and the folder at commit df229b1. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • node
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • bitovi.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Visual Diff loads about 2.9k tokens when it runs. Until then it costs about 82 tokens; SKILL.md has 994 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~82
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from bitovi/ai-enablement-prompts at commit df229b1, republished under its MIT licence (© bitovi). 994 words, ~2,911 tokens.

Download SKILL.mdSave it as .claude/skills/visual-diff/SKILL.md (or your agent's skills folder).
name
visual-diff
description
Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML corrections. Use when replicating an existing page or component, verifying visual accuracy, or checking responsive fidelity.

Skill: Visual Diff

Compare two URLs visually — a baseline (e.g. production site) and a current (e.g. local dev server or Storybook story) — to find pixel-level differences and guide corrections.


When to Use

  • Replicating an existing page or section in Storybook or the Astro site
  • Verifying visual accuracy of a component against a reference design
  • Checking responsive fidelity across breakpoints after style changes
  • Iterating on CSS/HTML until a component matches its reference

When NOT to Use

  • Content-only changes (text updates, copy edits) where layout is unchanged
  • Comparing designs from Figma — use the Figma MCP skill instead
  • Performance or accessibility audits — use Lighthouse or the a11y addon

Prerequisites

Before starting, confirm:

  1. Playwright MCP is configured in .vscode/mcp.json with --caps=vision
  2. pixelmatch and pngjs are installed: check package.json devDependencies
  3. The baseline URL is accessible (external site, or a running server)
  4. The current URL is accessible (dev server on :4321, Storybook on :6006, etc.)
  5. The temp/ directory exists in the workspace root (it's gitignored)

If the dev server or Storybook isn't running, start them using the VS Code tasks:

  • Dev server: use the Dev Server task
  • Storybook: use the Storybook task

Workflow

Step 1: Receive inputs

The agent needs:

InputRequiredExample
Baseline URLYeshttps://www.bitovi.com/
Current URLYeshttp://localhost:4321/ or http://localhost:6006/?path=/story/card--default
CSS selectorNo#hero-section or .card-grid (for element-scoped comparison)
BreakpointsNoDefaults to mobile (375×667), tablet (768×1024), desktop (1280×720)
Step 2: Screenshot the baseline
Component-scoped comparison (preferred when comparing a single component)

When comparing a specific component — especially when the Storybook story renders only that component but the baseline page has a full page around it — crop to the component's bounding box so the diff isn't polluted by unrelated page sections (nav bars, sticky overlays, other modules above/below).

How to crop on the baseline page:

  1. Navigate to the baseline URL
  2. Resize viewport to { width: 1280, height: 720 }
  3. Scroll the target element into view:
    js
    () => document.querySelector('<selector>').scrollIntoView({ behavior: 'instant', block: 'start' })
  4. Measure the component's rendered height:
    js
    () => document.querySelector('<selector>').getBoundingClientRect().height
  5. Resize the viewport height to match that exact height (keeps width constant):
    js
    mcp_playwright_browser_resize → { width: 1280, height: <measured height> }
  6. Take the screenshot — it now captures only the component area.

Background bleed warning: What's visible behind the component will differ between Storybook (blank) and the baseline page (other modules). Common cases: sticky/local nav bars overlapping the top, modals/overlays with other page content visible behind them, and partially transparent components. These residual diffs cluster outside the component's own content and are not actionable — ignore them.

How to crop on the Storybook story:

Storybook iframe.html renders only the component with no surrounding chrome — no resizing needed. Just navigate and screenshot:

mcp_playwright_browser_navigate → { url: "http://localhost:6006/iframe.html?id=<story-id>&viewMode=story" }
mcp_playwright_browser_resize → { width: 1280, height: <same height as baseline crop> }
mcp_playwright_browser_take_screenshot → { filename: "temp/vdiff-current-desktop.png" }
Full-page viewport screenshot (when comparing full pages)
1. mcp_playwright_browser_navigate → { url: "<baseline-url>" }
2. mcp_playwright_browser_resize → { width: 1280, height: 720 }
3. mcp_playwright_browser_wait_for → { time: 2 }       # let page fully render
4. mcp_playwright_browser_take_screenshot → {
     type: "png",
     filename: "temp/vdiff-baseline-desktop.png"
   }

Repeat for each breakpoint:

BreakpointWidthHeightFilename suffix
Mobile375667-mobile
Tablet7681024-tablet
Desktop1280720-desktop
Step 3: Screenshot the current

Repeat the exact same process for the current URL, using temp/vdiff-current-{breakpoint}.png filenames.

Important: Use the same viewport dimensions and the same cropping strategy (component-scoped or full-page) on both sides so the comparison is apples-to-apples.

Step 4: Run the diff script

For each breakpoint, run the visual-diff script in the terminal:

bash
node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-desktop.png \
  --current temp/vdiff-current-desktop.png \
  --output temp/vdiff-diff-desktop.png

The script outputs JSON to stdout:

json
{
  "totalPixels": 921600,
  "diffPixels": 4521,
  "diffPercent": 0.49,
  "width": 1280,
  "height": 720,
  "baselineDimensions": { "width": 1280, "height": 720 },
  "currentDimensions": { "width": 1280, "height": 720 },
  "dimensionsMismatch": false,
  "diffImagePath": "/absolute/path/to/temp/vdiff-diff-desktop.png"
}

If dimensionsMismatch is true, the images had different sizes. The script pads the smaller image with transparent pixels before comparing. This often indicates a layout issue worth investigating.

Show full SKILL.md (455 more words)Show less
Step 5: View the diff image

Start a temporary HTTP server to serve the temp/ directory, then navigate Playwright to the diff image:

bash
# Start server in background (run once per session)
npx -y http-server temp/ -p 8787 --cors -c-1 &

Then navigate Playwright to the diff image:

mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # triggers vision — agent can now see the diff

The --caps=vision flag on Playwright MCP means the agent can see the image directly in the screenshot output.

Note: file:// URLs are blocked by Playwright MCP, so the HTTP server is required. Start it once and reuse it for all diff images in the session.

Reading the diff image:

  • Red pixels = differences between baseline and current
  • Yellow pixels = anti-aliasing differences (usually ignorable)
  • Dimmed original = areas that match (shown at 30% opacity for context)
  • Large red clusters = structural issues (missing elements, layout shifts, wrong sizing)
  • Scattered red dots = sub-pixel rendering, font smoothing, or anti-aliasing (usually acceptable)
  • Red bands at edges = dimension mismatch or padding/margin differences
Step 6: Interpret and act

Combine the quantitative JSON data with the visual diff inspection:

diffPercentInterpretationAction
< 1%Visually identicalMinor sub-pixel differences only. No action needed.
1–5%Close matchInspect diff image for spacing, font weight, or border differences. Small CSS tweaks likely needed.
5–15%Notable differencesLayout shifts, color mismatches, or missing elements. Review the red clusters in the diff to identify which sections need work.
> 15%Significant gapMajor structural or styling differences. Focus on the largest red regions first — these indicate the biggest layout discrepancies.

When interpreting the diff image, note:

  • Where on the page are the red clusters? (top, middle, bottom, left, right)
  • Are they associated with specific elements? (navigation, hero, cards, footer)
  • Do the clusters suggest spacing issues, color differences, or missing content?
Step 7: Fix and re-diff
  1. Make CSS/HTML corrections based on the diff analysis
  2. Repeat Steps 3–6 (only re-screenshot the current URL)
  3. Continue until diffPercent reaches an acceptable level

Typical targets:

  • Exact replication: < 2%
  • Reasonable match: < 5%
  • Structural match (different content): < 15%

Full-page screenshots

By default, screenshots capture only the visible viewport. For long pages, use the fullPage option:

mcp_playwright_browser_take_screenshot → {
  type: "png",
  fullPage: true,
  filename: "temp/vdiff-baseline-desktop-full.png"
}

Warning: Full-page screenshots produce large images and slower diffs. Only use when comparing entire page layouts.


Storybook-specific tips

When screenshotting Storybook stories:

  1. Use the iframe URL for cleaner screenshots (no Storybook chrome):

    http://localhost:6006/iframe.html?id=components-card--default&viewMode=story
  2. Wait for render — Storybook stories may take a moment to hydrate:

    mcp_playwright_browser_wait_for → { time: 3 }
  3. Element screenshots work well for isolating the story content from any Storybook padding.


Threshold tuning

The --threshold flag (0 to 1) controls pixelmatch sensitivity:

ValueSensitivityUse case
0.05Very strictExact pixel matching, catches everything
0.1DefaultGood balance, ignores most anti-aliasing
0.2LenientTolerates font rendering differences across systems
0.3Very lenientOnly catches major color/layout differences
bash
node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-desktop.png \
  --current temp/vdiff-current-desktop.png \
  --output temp/vdiff-diff-desktop.png \
  --threshold 0.2

Example: Comparing a hero section

# 1. Screenshot baseline (production site hero)
mcp_playwright_browser_navigate → { url: "https://www.bitovi.com/" }
mcp_playwright_browser_resize → { width: 1280, height: 720 }
mcp_playwright_browser_wait_for → { time: 2 }
mcp_playwright_browser_snapshot → {}
# Find ref for hero section, e.g. ref="hero-[1]"
mcp_playwright_browser_take_screenshot → {
  type: "png",
  element: "hero section",
  ref: "hero-[1]",
  filename: "temp/vdiff-baseline-hero-desktop.png"
}

# 2. Screenshot current (Storybook story)
mcp_playwright_browser_navigate → { url: "http://localhost:6006/iframe.html?id=components-hero--default" }
mcp_playwright_browser_resize → { width: 1280, height: 720 }
mcp_playwright_browser_wait_for → { time: 3 }
mcp_playwright_browser_take_screenshot → {
  type: "png",
  filename: "temp/vdiff-current-hero-desktop.png"
}

# 3. Run diff (in terminal)
node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-hero-desktop.png \
  --current temp/vdiff-current-hero-desktop.png \
  --output temp/vdiff-diff-hero-desktop.png

# 4. Start temp server (once per session, in background terminal)
npx -y http-server temp/ -p 8787 --cors -c-1 &

# 5. View diff image via Playwright
mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-hero-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # triggers vision

# 6. Interpret: read JSON output + visually inspect diff
# 7. Fix styles, re-screenshot current, re-diff

Cleanup

All output files go to temp/ which is gitignored. To clean up after a session:

bash
rm -f temp/vdiff-*.png

© bitovi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in plugins/playwright/skills/visual-diff of bitovi/ai-enablement-prompts.

Open the folder on GitHubat commit df229b1

Compare with similar skills

Visual Diff next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Visual Diff compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Visual Diff this skillbitovi/ai-enablement-prompts121—~2.9kAutomated safety check: PassMIT
Common Web Visual TestingHoangNguyen0403/agent-skills-standard570—~760Automated safety check: PassMIT
Browser QAaffaan-m/ECC274k2 repos~1kAutomated safety check: PassMIT
Website Responsive Validationmacalbert/envilder138—~739Automated safety check: PassMIT
Economical Visual Testsigrlk/storybook-addon-test-codegen1541 repos~1.1kAutomated safety check: PassMIT
Extract Design Systemespennilsen/pi122—~2kAutomated safety check: PassMIT

Similar skills

  • Common Web Visual Testing

    HoangNguyen0403/agent-skills-standard

    Standardizes visual audits, responsive design, and behavioral testing for web apps.

    570 GitHub stars~760 tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Browser QA

    affaan-m/ECC

    Run automated post-deploy UI verification with a browser automation MCP (claude-in-chrome, Playwright, or Puppeteer): console-error and Core Web Vitals smoke checks, form and auth-flow interaction…

    274k GitHub starsUsed in 2 repos~1k tokens
    Frontend & DesignAuto-check passed
  • Playwright-based visual validation procedure for Envilder website changes.

    138 GitHub stars~739 tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed
  • Economical Visual Tests

    igrlk/storybook-addon-test-codegen

    Author economical visual tests — full visual coverage in the fewest billable snapshots.

    154 GitHub starsUsed in 1 repo~1.1k tokens
    Testing & QAAuto-check passed
  • Extract Design System

    espennilsen/pi

    Reverse-engineer a design system from a live website (public URL or localhost).

    122 GitHub stars~2k tokensUpdated 16 days ago
    Frontend & DesignAuto-check passed
  • Sanity Visual Regression

    sanity-io/sanity

    Official

    Add, review, and maintain Chromatic visual regression coverage in the Sanity monorepo via dev/storybook stories, the vitest browser-mode suite, and Playwright e2e snapshots.

    6.4k GitHub stars~3.4k tokensUpdated today
    Testing & QAAuto-check passed

More from bitovi/ai-enablement-prompts

All 40 skills in this repo
  • Component Registry

    bitovi/ai-enablement-prompts

    Track reusable UI components and unextracted patterns. An agent skill from bitovi/ai-enablement-prompts.

    121 GitHub stars~597 tokensUpdated 26 days ago
    Auto-check passed
  • Computed Styles

    bitovi/ai-enablement-prompts

    Extract and compare computed CSS styles between a baseline URL and a dev/Storybook URL using Playwright MCP evaluate calls.

    121 GitHub stars~2.4k tokensUpdated 26 days ago
    Auto-check passed
  • Create Plugin

    bitovi/ai-enablement-prompts

    A skill your agent uses when the user asks to "create a plugin", "add a plugin", "make a new plugin", "build a plugin", or wants to package skills into an installable plugin for this marketplace.

    121 GitHub stars~2k tokensUpdated 26 days ago
    Auto-check passed
  • Create React Modlet

    bitovi/ai-enablement-prompts

    Create React components, hooks, or utilities following the modlet pattern.

    121 GitHub stars~2.1k tokensUpdated 26 days ago
    Auto-check passed
  • Create Skill

    bitovi/ai-enablement-prompts

    A skill your agent uses when the user asks to "create a skill", "add a skill", "make a new skill", "build a skill", or wants to automate a repeated workflow into a reusable prompt.

    121 GitHub stars~1.6k tokensUpdated 26 days ago
    Auto-check passed
  • Create Skill

    bitovi/ai-enablement-prompts

    Create new Agent Skills for this project. An agent skill from bitovi/ai-enablement-prompts.

    121 GitHub stars~1.7k tokensUpdated 26 days ago
    Auto-check passed

Questions about Visual Diff

What does Visual Diff do?

Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML…. Visual Diff is an agent skill from bitovi/ai-enablement-prompts. Compare a baseline URL against a dev or Storybook URL by taking Playwright screenshots at multiple breakpoints, running a pixel-level image diff, and reporting results to guide style and HTML corrections.

When should I use Visual Diff?

Visual Diff fits situations like: replicating an existing page; verifying visual accuracy; checking responsive fidelity.

How do I install Visual Diff in Claude Code?

Run `npx skills add bitovi/ai-enablement-prompts --skill visual-diff -a claude-code`. Or copy the skill folder (plugins/playwright/skills/visual-diff in bitovi/ai-enablement-prompts) into .claude/skills/visual-diff in your project. Claude Code loads it when a task matches its description.

How do I install Visual Diff in Codex?

Run `npx skills add bitovi/ai-enablement-prompts --skill visual-diff -a codex`. Or copy the skill folder (plugins/playwright/skills/visual-diff in bitovi/ai-enablement-prompts) into .agents/skills/visual-diff in your project. Codex loads it when a task matches its description.

Can I use Visual Diff in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add bitovi/ai-enablement-prompts --skill visual-diff -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/visual-diff, .gemini/skills/visual-diff, .github/skills/visual-diff and .opencode/skills/visual-diff in your project.

What does Visual Diff need to run?

Going by SKILL.md and its folder, Visual Diff needs the command-line tools its instructions call (node and npx). Our summary lists: Node.js.

Does Visual Diff access the network?

SKILL.md names 1 domain. In commands or code: bitovi.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Visual Diff safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Visual Diff use?

Visual Diff is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Visual Diff use?

About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Visual Diff?

Skills that share tags, products or a category with Visual Diff: Common Web Visual Testing (HoangNguyen0403/agent-skills-standard, 570 stars), Browser QA (affaan-m/ECC, 274k stars), Website Responsive Validation (macalbert/envilder, 138 stars) and Economical Visual Tests (igrlk/storybook-addon-test-codegen, 154 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Visual Diff?

bitovi (a GitHub organization) maintains it in bitovi/ai-enablement-prompts, which has 121 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on September 11, 2026.

Source: bitovi/ai-enablement-prompts on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.