From visual-eyes
Give Claude Code eyes to see and analyze running web applications. Use when: user asks for a screenshot, mentions a visual bug, broken layout, "how does it look", "take a screenshot", "visual regression", "compare before and after", "test the UI", "show me the screen", or any reference to the visual appearance of a running app.
How this skill is triggered — by the user, by Claude, or both
Slash command
/visual-eyes:visual-eyesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill lets Claude see locally running web applications, identify visual
This skill lets Claude see locally running web applications, identify visual problems, and fix the code automatically.
Available tools in scripts/:
scripts/screenshot.sh - Capture a screenshot of a URLscripts/compare.sh - Compare two screenshots and generate a visual diffThe scripts live inside the skill directory. Resolve the path at runtime:
SKILL_DIR="$HOME/.claude/skills/visual-eyes"
ALWAYS run scripts with the correct arguments. See the usage sections below.
1. Capture a screenshot of the application
2. Read the PNG file with the Read tool (multimodal vision)
3. Identify visual problems
4. Fix the code
5. Capture a new screenshot
6. Compare visually - is it correct now?
7. Iterate until it looks right
bash "$HOME/.claude/skills/visual-eyes/scripts/screenshot.sh" \
"http://localhost:3000" \
"/tmp/visual-eyes-capture.png"
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-mobile.png" \
--viewport-size "390,844" \
--wait-for-timeout 2000
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-full.png" \
--viewport-size "1280,800" \
--full-page \
--wait-for-timeout 2000
Replace the URL with $ARGUMENTS when the user provides a custom route or URL.
Examples: /dashboard, http://localhost:5173/settings, http://localhost:8000
Default URL: http://localhost:3000 when the user does not specify one.
for ROUTE in "/" "/dashboard" "/settings" "/profile"; do
SLUG=$(echo "$ROUTE" | tr '/' '-')
npx playwright screenshot "http://localhost:3000${ROUTE}" \
"/tmp/visual-eyes${SLUG}.png" \
--viewport-size "1280,800" \
--wait-for-timeout 2000
echo "Captured: /tmp/visual-eyes${SLUG}.png"
done
Then use the Read tool on each PNG file to analyze it visually.
When you read a PNG with the Read tool, check the following:
When you identify a visual problem:
bash "$HOME/.claude/skills/visual-eyes/scripts/screenshot.sh" \
"http://localhost:3000" \
"/tmp/visual-eyes-after-fix.png"
Use when the user wants to compare the state before and after a change.
cp /tmp/visual-eyes-capture.png /tmp/visual-eyes-baseline.png
bash "$HOME/.claude/skills/visual-eyes/scripts/screenshot.sh" \
"http://localhost:3000" \
"/tmp/visual-eyes-after.png"
bash "$HOME/.claude/skills/visual-eyes/scripts/compare.sh" \
"/tmp/visual-eyes-baseline.png" \
"/tmp/visual-eyes-after.png" \
"/tmp/visual-eyes-diff.png"
Then use Read on /tmp/visual-eyes-diff.png to see exactly what changed.
Red pixels indicate modified areas. More red means bigger difference.
To check full responsive behavior:
# Desktop
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-desktop.png" \
--viewport-size "1280,800" --wait-for-timeout 2000
# Tablet
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-tablet.png" \
--viewport-size "768,1024" --wait-for-timeout 2000
# Mobile
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-mobile.png" \
--viewport-size "390,844" --wait-for-timeout 2000
Read all three PNGs with Read and compare the layout at each size.
If the screenshot fails with a connection error, inform the user: "The server is not running at localhost:3000. Please start the server first."
Suggestions for how to start it (try to identify from the project):
npm run devnpm run devuvicorn main:app --reloadpython manage.py runserverIf the error is about missing browsers:
npx playwright install chromium
Wait for installation and try the screenshot again.
If the page appears blank or shows a loading spinner, increase the timeout:
npx playwright screenshot "http://localhost:3000" "/tmp/visual-eyes-capture.png" \
--viewport-size "1280,800" \
--wait-for-timeout 5000
For pages with authentication or complex state, use Python with Playwright:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1280, "height": 800})
page.goto("http://localhost:3000")
page.wait_for_load_state("networkidle")
page.wait_for_timeout(2000)
page.screenshot(path="/tmp/visual-eyes-capture.png", full_page=False)
browser.close()
print("Screenshot saved: /tmp/visual-eyes-capture.png")
All temporary files live in /tmp/visual-eyes-* to avoid polluting the project.
| File | Use |
|---|---|
/tmp/visual-eyes-capture.png | Current main screenshot |
/tmp/visual-eyes-baseline.png | Baseline for comparison |
/tmp/visual-eyes-after.png | After modifications |
/tmp/visual-eyes-diff.png | Visual regression diff |
/tmp/visual-eyes-desktop.png | Desktop 1280x800 |
/tmp/visual-eyes-tablet.png | Tablet 768x1024 |
/tmp/visual-eyes-mobile.png | Mobile iPhone |
/tmp/visual-eyes-full.png | Full page (scroll) |
/tmp/visual-eyes-{route}.png | Specific routes |
Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub dehor-labs/visual-eyes