Skip to main content
Glama

looksy

CI License: MIT

Screenshot any URL from the command line. Built for AI-assisted development — lets Claude Code (or any AI) see rendered pages and iterate on designs visually.

Zero config. One command. Works with any framework.

looksy https://mysite.com --design    # Full-page screenshot + compact metadata

Features

  • Screenshot any URL — local files (auto-served), dev servers, deployed sites

  • AI-optimized output — metadata sidecar with exact CSS values, not just pixels

  • Visual regression — baseline save/diff with pixel-level change detection

  • Accessibility audits — WCAG contrast, landmarks, heading structure, missing labels

  • Anti-fingerprint audits — class audit (with recurring class combos), font sources, asset hashes, SEO, JSON-LD schema

  • Structural fingerprinting — cross-site similarity scoring with fingerprint collect/compare (8 dimensions including inline script hashes)

  • Tailwind utility profile--tailwind groups class names by category (spacing, sizing, colors, layout, typography, borders, animation)

  • Component-level contrast — React fiber walk maps WCAG failures back to file:line source location

  • Theme validation — WCAG AA/AAA checks for theme color configs, no browser needed

  • Batch mode — screenshot multiple pages or directory trees in one command

  • Design suggestions — actionable fix recommendations with exact CSS values for contrast, a11y, SEO

  • Layout debugging — flex/grid container overlay with numbered labels

  • Responsive audit — overflow, touch targets, text size checks at 3 breakpoints

  • Visual regression gate — one-command guard subcommand for CI/CD

  • Delta tracking — incremental diffs showing only what changed (~80 tokens)

  • Design spec validation — validate pages against a JSON specification

  • Component catalog — multi-selector element capture with grid composite

  • Capture history — timestamped timeline of all captures per URL

  • Performance analysis — bundle analysis, image audit, compression, third-party impact, cache audit, critical path, resource hints, server timing

  • Performance budgets — CI/CD gate with --budget (exit code 1 on failure)

  • One-command perf audit--speed runs all performance modules in one flag

  • Token-efficient — three tiers: full meta (~2,500 tokens), compact (~1,000), text-only (~100)

  • CI/CD ready--fail-on-aa (with failure details to stderr), --budget, --json output, exit codes

  • Fast — persistent Chromium server cuts captures from ~2s to ~100ms

  • Security hardened — CSS selector injection prevention, path traversal guard, TOCTOU race elimination, restrictive /tmp permissions

  • Strict flag parsing — typos like --contrast-aa error immediately instead of being silently ignored

  • Configurable storageLOOKSY_DIR env var for persistent baselines in CI (default: /tmp/looksy)

  • MCP integration — runs as a tool server for Claude Code

Related MCP server: ScreenshotRender MCP Server

Install

Install straight from GitHub (not yet published to npm):

npm install -g github:atre/looksy

Or from source:

git clone https://github.com/atre/looksy.git
cd looksy
npm install
npm run build
npm link

Looksy auto-installs Playwright Chromium on first install. If it doesn't, run:

npx playwright install chromium

Requires Node.js 18.3+.

PATH (mise / non-interactive shells)

npm link (or a global install) only lands looksy on PATH for shells that source your normal shell rc. Non-interactive shells — CI steps, cron, an agent's own tool-call shell — often skip that, especially with a version manager like mise managing node: the shim directory isn't on PATH until mise has hooked the shell, which a non-interactive shell frequently hasn't done. Symptom: looksy: command not found even though npm link reported success.

Fixes, in order of preference:

# 1. Point at the linked global bin explicitly (works regardless of shell/mise state)
#    (npm bin -g was removed in npm 9 — use npm prefix instead)
"$(npm prefix -g)/bin/looksy" <url>

# 2. With mise, activate its shims for the current shell
mise activate bash   # or: mise activate zsh
looksy <url>

# 3. Fallback that always works — run the built CLI entry point directly with node,
#    no PATH resolution involved at all:
node /path/to/looksy/dist/cli.js <url>

Option 3 is the most portable one for scripts/CI: it has no dependency on PATH, npm link, or a version manager being initialized — only that dist/ has been built (npm run build).

Quick Start

# Start persistent browser (optional but recommended — ~100ms vs ~2s per capture)
looksy --serve

# Screenshot with metadata
looksy http://localhost:3000 --design

# Check accessibility
looksy http://localhost:3000 --check "contrast:aa"

# Batch audit multiple pages
looksy http://localhost:3000 --pages "/,/pricing,/about" --contrast --fail-on-aa

# Batch audit build output directory
looksy batch test-builds/ --glob "*/index.html" --report --contrast

# Fleet audit across live domains (defaults to contrast + a11y, exit 1 on AA failure)
looksy fleet https://site-a.com https://site-b.com

# Structural fingerprint (cross-site similarity detection)
looksy fingerprint collect https://site-a.com --save site-a
looksy fingerprint collect https://site-b.com --save site-b
looksy fingerprint compare site-a site-b
looksy fingerprint diff site-a-v1 site-a-v2          # What changed between versions
looksy fingerprint collect-batch --serve-dir ./builds --glob "*/index.html"  # Batch
looksy fingerprint list

# Theme validation (no browser needed)
looksy validate-theme theme.json
looksy validate-theme theme.json --compact --fail-on-aa

Workflows

Design iteration (most common)

looksy --serve                                    # Start once per session
looksy <url> --design --name step1                # Full-page + compact metadata, labeled
looksy <url> --check "contrast:aa"                # WCAG AA pass/fail with failing element details
looksy <url> --diff-inline /tmp/looksy/preview-step1.png --name step2  # Before/after

Batch site audit

looksy <url> --pages "/,/pricing,/about" --full           # Screenshot multiple pages
looksy <url> --pages "/,/pricing" --design --concurrency 2  # Heavy analysis with limited parallelism
looksy <url> --pages "/,/pricing" --contrast --fail-on-aa # Contrast check all pages (details to stderr)
looksy <url> --pages "/,/pricing" --consistency           # Flag cross-page divergences
looksy <url> --pages "/,/pricing" --locales "en,de"       # Cross-product: 4 pages

Batch directory audit

looksy batch test-builds/ --glob "*/index.html" --report --contrast  # All matching files
looksy --serve-dir ./build --pages "/,/about" --report               # Serve dir + pages
looksy ./build/index.html --report                                   # Auto-serve local file

Structural fingerprinting

looksy fingerprint collect https://site-a.com --save site-a   # Collect DOM fingerprint
looksy fingerprint collect https://site-b.com --save site-b   # Collect another
looksy fingerprint collect --serve-dir ./build --save my-site  # Fingerprint a static build
looksy fingerprint collect-batch --serve-dir ./dist --glob "*/index.html"  # Batch collect
looksy fingerprint compare site-a site-b                       # 0-100 similarity score
looksy fingerprint diff v1 v2                                  # Show what changed between versions
looksy fingerprint list                                        # List saved fingerprints

Theme validation

looksy validate-theme theme.json                  # WCAG AA/AAA check for all color pairs
looksy validate-theme theme.json --compact        # Condensed output
looksy validate-theme theme.json --fail-on-aa     # Exit code 1 on AA failures (CI/CD)

No browser needed — validates color contrast ratios directly from a theme config file.

Visual regression

looksy save <url> homepage                        # Save baseline
# ... make changes ...
looksy diff <url> homepage                        # Pixel diff → /tmp/looksy/diff.png
looksy diff before.png after.png                  # Or compare two local files

Visual regression gate (CI/CD)

looksy guard homepage https://staging.example.com           # Auto-creates baseline on first run
looksy guard homepage https://staging.example.com           # Compares on subsequent runs
looksy guard homepage https://staging.example.com --threshold 1.0  # Custom threshold

One command that auto-creates baselines, diffs on subsequent runs, and exits with code 1 if changes exceed the threshold.

Watch mode with auto-serve

looksy --watch ./src                              # Auto-serves ./src, re-screenshots on change
looksy <url> --watch ./src                        # Watch with explicit URL

When no URL is given, --watch auto-serves the watched directory via HTTP.

Performance audit

looksy <url> --speed                              # Full perf audit (all modules, one command)
looksy <url> --bundles --images --compression      # Individual modules
looksy <url> --critical-path --server-timing       # Render-blocking + TTFB breakdown
looksy <url> --third-party --cache-audit           # Third-party impact + caching
looksy <url> --resource-hints                      # Preload/preconnect suggestions
looksy <url> --budget "totalJS:200KB,FCP:1800"     # CI gate (exit 1 on failure)
looksy <url> --budget budget.json                  # Budget from JSON file

Cheap verification loop

looksy <url> --report                             # Text-only (~100 tokens, no screenshot)
looksy <url> --check "sticky header, contrast:aa" # Pass/fail assertions (~50 tokens)

# Want the PNG too, e.g. to eyeball it later? Add -o/--name/--suffix — an explicit
# output path is honored even in --report's normally screenshot-free text-only mode.
looksy <url> --report --name cart                 # Text summary AND preview-cart.png

Usage

# Basic screenshot
looksy <url>                                    # Screenshot to /tmp/looksy/preview.png
looksy ./mock.html                              # Screenshot a local file (auto-served via HTTP)
looksy <url> --meta                             # + metadata sidecar (.meta.md)
looksy <url> --annotate --meta                  # + numbered bounding boxes on elements
looksy <url> --perf --meta                      # + Core Web Vitals (FCP, LCP, CLS, TTFB)
looksy <url> -o ./screenshot.png                # Custom output path

# Viewports
looksy <url> --mobile                           # Mobile viewport (390x844)
looksy <url> --tablet                           # Tablet viewport (768x1024)
looksy <url> --multi                            # Desktop + mobile in one shot (parallel)
looksy <url> --width 1440 --height 900          # Custom viewport

# Output naming
looksy <url> --suffix hero                      # Output: preview-hero.png
looksy <url> --name hero                        # Same as --suffix (alias)

# Capture options
looksy <url> --full                             # Full page scroll capture
looksy <url> --full --max-height 2000           # Full page capped at 2000px
looksy <url> --selector ".hero-section"         # Screenshot specific element
looksy <url> --wait 2000                        # Wait ms before screenshot
looksy <url> --dark                             # Emulate prefers-color-scheme: dark
looksy <url> --design                           # Shorthand for --full --meta --compact --fonts --css-vars --contrast --suggest
looksy <url> --fold                             # Above-fold only (viewport height)
looksy <url> --micro                            # Thumbnail mode (640px, JPEG q40)
looksy <url> --selector ".card" --all           # Screenshot every matching element
looksy <url> --design-spec ./spec.json          # Validate against design spec
looksy <url> --diff-report baseline-name        # Semantic diff vs saved baseline
looksy <url> --format jpeg --quality 80         # JPEG output (smaller files)

# Interact before capture
looksy <url> --interact "click:.btn,wait:500"   # Click, wait, then screenshot
looksy <url> --interact "scroll:800,wait:200"   # Scroll down, then screenshot
looksy <url> --interact "scroll-to:.footer"     # Scroll element into view
looksy <url> --interact "type:.search=hello"    # Type into input, then screenshot
looksy <url> --interact "hover:.menu"           # Hover element, then screenshot

# CSS injection (test visual changes without editing files)
looksy <url> --inject "body { background: red }" # Inject CSS before capture

# Navigation timeout
looksy <url> --timeout 60000                    # Custom timeout (default: 30000ms)

# Force a hostname to a specific IP (stale local DNS after a fresh domain cutover)
looksy <url> --host-resolver staging.example.com:203.0.113.5

# HTML pipe (no file needed)
echo '<div>hello</div>' | looksy --html         # Screenshot piped HTML snippet

# Side-by-side before/after diff
looksy <url> --diff-inline before.png           # Compare current vs "before" PNG

# Visual regression (baseline diff)
looksy save <url> <name>                        # Save screenshot as named baseline
looksy diff <url> <name>                        # Compare current vs baseline → diff.png
looksy diff before.png after.png                # Compare two local image files → diff.png
looksy list                                     # List saved baselines

# Batch directory mode
looksy batch <dir> --glob "*/index.html"        # Batch screenshot matching files (auto-served)
looksy batch <dir> --glob "**/*.html" --report  # With analysis
looksy --serve-dir ./build --pages "/,/about"   # Serve directory + batch pages

# Watch mode
looksy <url> --watch ./src                      # Re-screenshot when files change (with diff %)
looksy --watch ./src                            # Auto-serves ./src, re-screenshots on change

# Analysis (appended to .meta.md)
looksy <url> --a11y                             # Accessibility audit
looksy <url> --contrast                         # WCAG color contrast check (semantic grouping)
looksy <url> --contrast --fail-on-aa            # Exit code 1 + failure details to stderr
looksy <url> --contrast --fail-on-aaa           # Exit code 1 + failure details to stderr
looksy <url> --contrast --visible-only          # Skip hidden elements (dropdowns, modals)
looksy <url> --network                          # Network waterfall
looksy <url> --css-vars                         # CSS custom properties from :root
looksy <url> --fonts                            # Font loading verification
looksy <url> --lighthouse                       # Extended perf (memory, long tasks, INP)
looksy <url> --dom-stats                        # DOM complexity one-liner
looksy <url> --links                            # Dead link checker (HEAD all hrefs)
looksy <url> --coverage --meta                  # CSS/JS code coverage
looksy <url> --class-audit                      # Extract all CSS class names + recurring class combos
looksy <url> --tailwind                         # Tailwind utility profile (groups by category, implies --meta)
looksy <url> --font-sources                     # List all font file URLs and CDN domains
looksy <url> --asset-hashes                     # List hashed asset filenames (build fingerprints)
looksy <url> --seo                              # SEO audit (robots.txt, sitemap, og, canonical)
looksy <url> --schema                           # JSON-LD structured data extraction + validation

# Advanced capture
looksy <url> --sweep                            # 5 responsive breakpoints (parallel)
looksy <url> --sweep --sweep-widths 375,768     # Custom breakpoint widths
looksy <url> --sweep --check "contrast:aa"      # Check contrast at all breakpoints
looksy <url> --sections                         # Screenshot each section individually
looksy <url> --filmstrip 2000                   # 8-frame filmstrip over 2s
looksy <url> --filmstrip 2000 --filmstrip-scroll 1200  # Scroll 1200px across the filmstrip
looksy <url> --compare https://other.com        # Visual diff between two URLs
looksy <url> --compare https://other.com --class-audit  # + CSS class fingerprint overlap
looksy <url> --pdf                              # Export as PDF
looksy <url> --record 3000                      # Record 3s video (WebM)
looksy <url> --har                              # Export HTTP Archive (.har)

# Token-saving
looksy <url> --compact --meta                   # Condensed metadata (~50-60% fewer tokens)
looksy <url> --report                           # Text-only summary (~100 tokens, no screenshot)
looksy <url> --check "sticky header, dark bg"   # Pass/fail checklist (no screenshot)
looksy <url> --check "contrast:aa"              # WCAG AA pass/fail with failing elements
looksy <url> --check "text:Hello, selector:h1"  # Extended check grammar
looksy <url> --check "count:3 .card"            # Exact element count
looksy <url> --check "dark bg:.hero"            # Scoped background luminance check
looksy <url> --check "no generator"             # Verify no <meta name="generator"> tag
looksy <url> --check "translated"               # Flag untranslated text on non-English pages
looksy <url> --audit "border-primary/10"        # Flag deprecated design token usage
looksy <url> --meta --perf --json               # Machine-parseable JSON output

# Performance analysis
looksy <url> --speed                            # Full perf audit (all modules + report)
looksy <url> --bundles                          # JS bundle analysis (chunks, categories)
looksy <url> --images                           # Image audit (oversized, lazy/eager, format)
looksy <url> --compression                      # Compression check (gzip/brotli/none)
looksy <url> --third-party                      # Third-party resource impact by origin
looksy <url> --cache-audit                      # Cache policy audit
looksy <url> --critical-path                    # Critical rendering path analysis
looksy <url> --resource-hints                   # Resource hints audit (preload/preconnect)
looksy <url> --server-timing                    # Server timing + TTFB breakdown
looksy <url> --budget "totalJS:200KB,FCP:1800"  # Performance budget gate (CI/CD)
looksy <url> --budget budget.json               # Budget from JSON file

# New analysis & capture modes
looksy <url> --delta                            # Incremental diff vs previous (~80 tokens)
looksy <url> --suggest                          # Actionable fix recommendations
looksy <url> --layout --meta                    # Flex/grid overlay + legend
looksy <url> --responsive-check                 # Responsive audit (3 breakpoints)
looksy <url> --responsive-check --target-size 24  # AA touch-target threshold (default 44 = AAA)
looksy <url> --components ".hero,.cta"          # Screenshot elements + grid composite
looksy <url> --history                          # Save to timestamped timeline
looksy guard <name> <url>                       # Visual regression gate (auto-baseline)
looksy guard <name> <url> --threshold 1.0       # Custom pixel change threshold
looksy history                                  # Show capture history timeline

# Batch mode
looksy <url> --pages "/,/pricing,/contact"      # Screenshot multiple pages in one command
looksy <url> --pages "/,/pricing" --concurrency 3  # Limit parallel captures (default: 3 with --design)
looksy <url> --pages "/,/pricing" --output-dir ./shots  # Output to directory
looksy <url> --pages "/,/pricing" --locales "en,de"  # Cross-product: 4 pages
looksy <url> --pages "/,/pricing" --consistency  # Flag cross-page divergences
looksy <url> --pages "/,/pricing" --contrast    # Consolidated contrast summary
looksy <url> --i18n-check "/en/pricing,/de/pricing"  # Structural comparison of locale pages
looksy --urls "https://a.com,https://b.com" --batch-report  # Multi-domain batch
looksy --url-file sites.txt --contrast          # URLs from a file (one per line, # comments)
looksy fleet https://a.com https://b.com        # Fleet audit (contrast+a11y, batch-report.md)
looksy --cat-meta                               # Print last meta file to stdout

# Structural fingerprint (cross-site similarity)
looksy fingerprint collect <url> --save <name>   # Collect DOM fingerprint from URL
looksy fingerprint collect --serve-dir <dir> --save <name>  # Fingerprint a static build
looksy fingerprint collect-batch --serve-dir <dir> [--glob "*/index.html"]  # Batch collect
looksy fingerprint compare <name1> <name2>       # 0-100 similarity score (or N names for matrix)
looksy fingerprint diff <before> <after>         # Show what changed between two versions
looksy fingerprint list                          # List saved fingerprints

# Theme validation (no browser needed)
looksy validate-theme theme.json                # WCAG AA/AAA check for all color pairs
looksy validate-theme theme.json --compact --fail-on-aa  # CI/CD gate

# Auth
looksy <url> --cookie "session=abc123"          # Set cookies before capture
looksy <url> --storage-state ./auth.json        # Playwright storage state file
looksy <url> --basic-auth user:password         # HTTP basic auth

# Speed
looksy --serve                                  # Start persistent Chromium (~100ms captures)
looksy <url>                                    # Uses running server automatically
looksy --serve-stop                             # Stop server

# MCP integration
looksy --mcp                                    # Run as MCP tool server for Claude Code

# Utility
looksy --version                                # Print version number
LOOKSY_DIR=./baselines looksy <url>             # Custom base directory (CI persistent baselines)

Output

Screenshots save to /tmp/looksy/preview.png by default (overwritten each time). Set LOOKSY_DIR env var to change the base directory (e.g., LOOKSY_DIR=./baselines for persistent CI storage). Every invocation prints page dimensions and timing:

Page: 1280x4200px "My Site" (1.2s)

Metadata sidecar (--meta)

Writes .meta.md alongside the PNG with:

  • Heading hierarchy (H1-H6 tree)

  • Color palette (computed RGB values)

  • Font stack

  • Console errors and broken images

  • Key element computed styles (font-size, padding, margin, colors, display, gap, dimensions)

  • Above/below fold tagging

  • Image optimization hints (natural vs display dimensions)

Analysis flags

Flag

What it does

Tokens

--design

Shorthand for --full --meta --compact --fonts --css-vars --contrast --suggest

~1,000

--meta

Full metadata sidecar

~2,500

--compact

Condensed metadata (no tables, shorthand CSS)

~1,000

--report

Text-only summary, no screenshot

~100

--check "<assertions>"

Pass/fail checklist, no screenshot

~50

--annotate

Numbered bounding boxes on elements

--perf

Core Web Vitals (FCP, LCP, CLS, TTFB)

--a11y

Accessibility audit (landmarks, headings, issues)

--contrast

WCAG AA/AAA contrast ratios with semantic grouping (+ React file:line source when available)

--contrast-limit <n>

Max elements sampled by contrast checks (default 150; reports coverage when capped)

--network

Network waterfall (top 15 slowest resources)

--css-vars

CSS custom properties from :root

--fonts

Font loading verification

--lighthouse

Extended perf (memory, long tasks, INP)

--dom-stats

DOM complexity (elements, depth, inline styles)

--links

Dead link checker

--coverage

CSS/JS code coverage via CDP

--class-audit

All CSS class names + recurring class combos (component shape detection)

--tailwind

Tailwind utility profile by category (auto-implies --meta)

--font-sources

Font file URLs and CDN domains

--asset-hashes

Hashed asset filenames (build fingerprints)

--seo

SEO audit (robots.txt, sitemap, OG, canonical, schema)

--schema

JSON-LD structured data extraction + validation

--design-spec <json>

Validate page against a design spec (fonts, colors, spacing)

--diff-report <name>

Semantic diff against a saved baseline

--suggest

Actionable fix recommendations (contrast, a11y, SEO)

~100

--delta

Incremental diff vs previous capture (only what changed)

~80

--layout

Flex/grid container overlay with numbered labels

--responsive-check

Responsive audit at 3 breakpoints (overflow, touch, text)

--target-size <n>

Touch-target threshold for --responsive-check (default 44 = AAA, 24 = AA)

--components <sels>

Multi-selector element capture with grid composite

--history

Save capture to timestamped timeline

guard <name> <url> (or --guard <name>)

Visual regression gate (auto-baseline, threshold, CI exit codes)

--audit "<pattern>"

Design token audit

--speed

Compound: all 11 performance modules + --report --compact

--bundles

JS bundle analysis (chunks, categories, large bundles)

--images

Image audit (oversized, lazy/eager, format, dimensions)

--compression

Compression check (gzip/brotli/none per text resource)

--third-party

Third-party resource impact by origin (categorized)

--cache-audit

Cache policy audit (status, TTL, issues)

--critical-path

Critical rendering path (blocking resources, LCP, TTFB)

--resource-hints

Resource hints audit (preload/preconnect suggestions)

--server-timing

Server timing + TTFB breakdown (DNS/TCP/TLS/server)

--budget <config>

Performance budget gate (exit code 1 on failure)

fingerprint collect/compare

Structural fingerprint, 0-100 similarity score (8 dimensions incl. inline script hashes)

fingerprint collect-batch

Batch fingerprint collection from a directory

fingerprint diff

Show what changed between two fingerprint versions

validate-theme

WCAG AA/AAA contrast for theme color configs (no browser)

--design-audit

Pre-launch QA: --full --compact --contrast --seo --schema --fonts --font-sources --suggest --responsive-check + --check "no generator, self-hosted-fonts, contrast:aa"

--batch-report

With --pages/--urls: consolidated markdown table

--urls "<a,b>" / --url-file <path>

Multi-domain batch capture (shared browser, concurrency-limited)

fleet <url...>

Multi-URL audit: defaults to --contrast --a11y --compact, writes batch-report.md, exit 1 on AA failure

--json

Output .meta.json instead of .meta.md

--inject <css>

Inject custom CSS before capture

--timeout <ms>

Navigation timeout (default: 30000ms)

--host-resolver <domain:ip>

Force one hostname to one IP for this run (stale local DNS)

--concurrency <n>

Max parallel page captures (default: 3 with --design/--full/--speed, unlimited otherwise)

--output-dir <dir>

Output directory for batch captures

--foreground

With --serve: block in this process instead of detaching

--version

Print version number and exit

Check assertions

The --check flag supports these patterns:

Pattern

Example

What it checks

sticky header

--check "sticky header"

Header position: sticky/fixed

dark bg / light bg

--check "dark bg"

Body background luminance

dark bg:.sel

--check "dark bg:.hero"

Scoped element luminance

text:phrase

--check "text:Sign Up"

Case-insensitive text search

selector:.css

--check "selector:.hero"

CSS selector presence

count:N .sel

--check "count:3 .card"

Exact element count

contrast:aa

--check "contrast:aa"

WCAG AA check with failing element details

contrast:aaa

--check "contrast:aaa"

WCAG AAA check with failing element details

no generator

--check "no generator"

Meta generator tag absence

no X

--check "no border-primary"

Absence check (class/style)

has .sel

--check "has .nav"

Presence check

visible .sel

--check "visible .modal"

Visibility check

hidden .sel

--check "hidden .tooltip"

Hidden check

translated

--check "translated"

Flag untranslated text on non-English pages

font:<sel>=<family>

--check "font:h1=Archivo Black"

Computed font-family check

bg:<sel>=<hex>

--check "bg:.hero=#3D3D3D"

Background color (±5 tolerance)

color:<sel>=<hex>

--check "color:h1=#ffffff"

Text color (±5 tolerance)

self-hosted-fonts

--check "self-hosted-fonts"

Fails if any external font domain found

no-google-fonts

--check "no-google-fonts"

GDPR: fails if Google Fonts detected

unique-footer

--check "unique-footer"

Footer presence (use with --pages for consistency)

unique-nav

--check "unique-nav"

Nav presence (use with --pages for consistency)

Batch mode

--pages screenshots multiple paths with a shared browser. Concurrency defaults to 3 when --design, --full, or --speed is active (prevents Chromium memory exhaustion). Override with --concurrency N.

looksy http://localhost:3000 --pages "/,/pricing,/contact"
# → preview-index.png, preview-pricing.png, preview-contact.png

Combine with --locales for cross-product expansion:

looksy http://localhost:3000 --pages "/,/pricing" --locales "en,de"
# → 4 pages: /en/, /en/pricing, /de/, /de/pricing

Use --consistency to flag divergences across pages (headings, colors, fonts, nav, footer). Use --i18n-check to compare two locale versions structurally.

Batch directory mode

looksy batch screenshots files matching a glob pattern with auto-served HTTP:

looksy batch test-builds/ --glob "*/index.html" --report --contrast
# → preview-site-a.png, preview-site-b.png, ...

Each file's parent directory is auto-served via HTTP, so root-relative paths (/_astro/, /_next/) resolve correctly. No manual python3 -m http.server needed.

Use --serve-dir with --pages for explicit directory serving. Clean URLs are supported — /about resolves to /about.html for Astro format:'file' builds and similar static site generators:

looksy --serve-dir ./build --pages "/,/about,/pricing" --report   # Clean URLs work
looksy --serve-dir ./build --pages "/index.html,/about.html" --report  # Explicit paths too

--serve-dir also works with fingerprint collect:

looksy fingerprint collect --serve-dir ./build --save my-site
looksy fingerprint collect-batch --serve-dir ./dist --glob "*/index.html"

Local file paths are also auto-served: looksy ./build/index.html serves the directory via HTTP instead of using file://.

Persistent server

looksy --serve starts a background Chromium server and detaches: it prints the pid and WS endpoint, then returns control to your shell/script — the browser keeps running after the command exits. All subsequent looksy invocations connect via WebSocket for ~100ms captures instead of ~2s cold starts. Idempotent — calling it again while a server is already running just prints its status and exits 0, it doesn't start a second one.

looksy --serve          # Start, detached (prints "server started (pid N)" + ws endpoint), returns immediately
looksy --serve          # Already running → prints "server already running (pid N)", exits 0
looksy <url>            # Uses server automatically
looksy --serve-stop     # Stop

Need the old blocking behavior (e.g. to supervise it yourself under systemd/pm2, or just & it manually) — looksy --serve --foreground runs chromium.launchServer in the current process and never returns until it's killed (Ctrl+C / SIGTERM).

Before this, plain --serve blocked the calling process forever — fine interactively (you just Ctrl+C or background it with &), but it silently hung any script or CI step that called it expecting a normal command that returns. --serve now does the backgrounding itself; --foreground is there for when you specifically want the old behavior.

MCP server

looksy --mcp runs as an MCP tool server over stdio, providing screenshot, save-baseline, diff-baseline, and list-baselines tools for direct Claude Code integration.

How It Works

AI coding assistants can read images but can't judge spacing, subtle colors, or pixel alignment from screenshots alone. The --meta sidecar fixes this by providing exact computed CSS values alongside the visual.

The iteration loop:

  1. Edit your template/component

  2. looksy <url> --design — full-page screenshot + compact metadata

  3. AI reads the PNG (layout, structure) + .meta.md (exact font-size, padding, colors, gap)

  4. AI fixes code with precise data, not guesswork

  5. Repeat

Real-world result: 4 iterations from blank to production-ready dark-mode landing page. ~15,800 tokens total (~4-5% of a conversation). With --compact: ~10,000 tokens (~2-3%). With --report + --check: ~2,000 tokens (~0.5%).

CI/CD Integration

# Fail build on WCAG AA contrast violations (failure details to stderr)
looksy https://staging.example.com --contrast --fail-on-aa

# JSON output for assertion scripts
looksy https://staging.example.com --meta --contrast --json
cat /tmp/looksy/preview.meta.json | jq '.contrast.aaFailures'

# Batch check all pages
looksy https://staging.example.com --pages "/,/pricing,/about" --check "contrast:aa"

# Batch check build output directory
looksy batch test-builds/ --glob "*/index.html" --contrast --fail-on-aa

# Performance budget gate
looksy https://staging.example.com --perf --bundles --budget "totalJS:200KB,FCP:1800"

Exit codes: 0 on success, 1 on failure, --fail-on-aa/--fail-on-aaa violations, --budget exceeded, or unknown flags (strict parsing).

Development

npm install
npm run build           # tsc → dist/
npm run dev             # tsc --watch
npm test                # Build + run all tests
npx vitest run          # Run tests only (skip build)
npx vitest              # Watch mode

Tests

326 tests across 43 test files:

  • Unit tests (tests/unit/) — 308 tests, no browser. Each test file mirrors a source module (e.g., cli.test.ts, contrast.test.ts, budget.test.ts). Covers: CLI parsing, interactions, metadata formatting, theme validation, fingerprinting (incl. inline script hashes + asset filenames), check assertions, static server, delta/diff-report, batch-report, design-audit, class-audit (incl. recurring combo detection), and 3-5 tests each for ~20 formatter modules (bundles, images, compression, cache-audit, etc.).

  • Integration tests (tests/integration/) — 18 tests across 3 files, real browser.

Architecture

See ARCHITECTURE.md for detailed component descriptions, data flow diagrams, and design decisions.

~70 source files, ~11,000 lines. Key components:

Component

File

Role

CLI

src/cli.ts

Arg parsing, routing, batch orchestration

Screenshot Engine

src/screenshot.ts

Core orchestrator, browser management

Server

src/server.ts

Persistent Chromium via WebSocket

Static Server

src/static-server.ts

HTTP server for local directories + glob file finder

Metadata

src/metadata.ts

Page data extraction + formatting

Contrast

src/contrast.ts

WCAG AA/AAA checker with semantic failure grouping

Check

src/check.ts

Pass/fail assertion engine (with contrast element details)

Report

src/report.ts

Lightweight text-only summary

Diff

src/diff.ts

Baseline save/load + pixel diff

Sweep

src/sweep.ts

Responsive breakpoint screenshots

Class Audit

src/class-audit.ts

CSS class extraction, recurring combo detection, fingerprint detection, cross-page compare

Tailwind

src/metadata.ts

Tailwind utility classification by category (spacing, sizing, colors, etc.)

SEO

src/seo.ts

SEO audit (robots.txt, sitemap, OG, canonical, schema)

Schema

src/schema.ts

JSON-LD structured data extraction + validation

Font Sources

src/font-sources.ts

Font file URL and CDN domain listing

Asset Hashes

src/asset-hashes.ts

Hashed asset filename detection

Fingerprint

src/fingerprint.ts

DOM fingerprint collection (8 dimensions incl. inline script hashes), cross-site similarity scoring

Validate Theme

src/validate-theme.ts

Theme color contrast validation (no browser)

Delta

src/delta.ts

Incremental diff vs previous capture

Suggest

src/suggest.ts

Actionable fix recommendations

Layout

src/layout.ts

Flex/grid container visual overlay

Responsive Check

src/responsive-check.ts

Responsive audit at 3 breakpoints

Components

src/components.ts

Multi-selector element capture with grid

History

src/history.ts

Timestamped capture timeline

Design Spec

src/design-spec.ts

Design specification validation

Diff Report

src/diff-report.ts

Semantic diff against baseline

Bundles

src/bundles.ts

JS bundle analysis (chunks, categories)

Images

src/images.ts

Image audit (oversized, lazy/eager, format)

Compression

src/compression.ts

Compression check (gzip/brotli/none)

Third-Party

src/third-party.ts

Third-party resource impact by origin

Cache Audit

src/cache-audit.ts

Cache policy audit

Critical Path

src/critical-path.ts

Critical rendering path analysis

Resource Hints

src/resource-hints.ts

Resource hints audit (preload/preconnect)

Server Timing

src/server-timing.ts

Server timing + TTFB breakdown

Budget

src/budget.ts

Performance budget gate

Navigate

src/navigate.ts

Shared error-resilient navigation (networkidledomcontentloaded)

Pixel Diff

src/pixel-diff.ts

Shared pixel comparison logic (diff threshold: dr+dg+db > 30)

MCP

src/mcp.ts

MCP tool server for Claude Code

Dependencies

Package

Purpose

playwright

Browser automation (Chromium only)

pngjs

PNG read/write for pixel diff + filmstrip

@modelcontextprotocol/sdk

MCP server (optional — only loaded with --mcp)

License

MIT

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Screenshot, diff, audit and sitemap-capture any web page — 5 MCP tools for AI agents.

  • Capture screenshots, detect visual regressions between page versions, and analyze with AI.

  • Screenshots, PDFs and Markdown from any URL or HTML for AI agents, via the SnapForge API

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/atre/looksy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server