Skip to content

voidmatcha/ui-clone-skills

Repository files navigation

ui-clone-skills — Clone any website into React + Tailwind

A Claude Code plugin that reverse-engineers any live website into a production-ready React + Tailwind component.

  • Uses the original CSS directly — downloads stylesheets, keeps original class names. No re-implementing from extracted values.
  • Near-zero vision tokens for verification — AE/SSIM image diff instead of reading screenshots with the LLM. Vision tokens only used in Phase E (final LLM review) when automated checks pass but semantic verification is needed.
  • Extracts real values from JS bundles — GSAP timelines, Framer Motion springs, Lenis scroll params, scroll-driven keyframes. No guessing.
  • Falls back to getComputedStyle when CSS is obfuscated (Tailwind, CSS-in-JS). Auto-detects site type.

When to use this — decision tree

Different inputs need different tools. Pick by what you have:

What you have Use
A live URL and want pixel-faithful React (real CSS, real animation params, scroll/hover behavior) ui-clone-skills ← you are here
A Figma file Builder.io / Anima
A screenshot (no source available) screenshot-to-code / v0
A text description (no reference) v0 / Lovable
A live URL and just want static HTML mirror (no React) wget --mirror / HTTrack

Why this exists: prompt-/screenshot-driven tools approximate what's visible. ui-clone-skills downloads the actual stylesheet, runs getComputedStyle against the rendered DOM, greps the JS bundle for GSAP/Framer Motion/Lenis parameters, and verifies the result against the original via AE/SSIM — so the output matches transitions and responsive behavior, not just the static layout.

When NOT to use: general "build me a UI from scratch" tasks (use v0/Lovable), Figma-driven workflows (use Builder/Anima), one-off CSS help (just ask Claude directly).

Design principles

These are the decisions that shape how the plugin is structured. They aim to keep agent sessions focused and bounded.

  • Real values, not guesses. Every number — font-size, easing curve, scroll offset, stagger delay — comes from getComputedStyle, raw CSS, or a JS bundle grep. The plugin refuses to ship approximations.
  • Near-zero vision tokens for comparison. AE and SSIM CLI tools handle pixel diff — the LLM never reads ref vs impl screenshots side-by-side. Vision tokens are only used when: (1) reading a single diff image on AE/SSIM failure, (2) Phase E final semantic review (~44K tokens, mandatory).
  • Progressive-disclosure sub-docs. Each SKILL.md contains only the pipeline and core rules (~5.9K tokens total across 3 skills). Detailed procedures live in 39 focused sub-docs loaded only when that step runs. Common paths stay lean; specialized paths expand on demand.
  • Single source of truth for transitions. transition-spec.json is produced once from bundle analysis. Implementation reads the spec, never re-greps the bundle — avoiding wasted work and the risk of picking the wrong conditional branch.
  • Automation over introspection. Python gates (python -m ui_clone.gate, python -m ui_clone.pipeline, auto-verify.sh) decide whether a step is complete. Agents don't self-certify "looks good enough."
  • No judgment, data only. Every decision must be backed by extracted data, captured screenshots, or script output. "Probably", "close enough", and "just a content difference" are forbidden — each has a documented failure case.

Skills

Skill Purpose
ui-reverse-engineering Full pipeline: URL → DOM/CSS/JS extraction → React + Tailwind component. Includes Webflow IX2 detection (Step W), transition coverage audit (Step 6d), canvas/WebGL/Three.js extraction.
ui-capture Baseline screenshots + transition capture + comparison page. Auto-detects custom scroll (Lenis, Locomotive). Classifies effects by trigger type.
visual-debug All visual comparison in one skill. Quick mode (AE/SSIM batch), full verification (Phase A→E with self-healing loop), section-level comparison, and transition behavior diff.

Requirements

Tested on: macOS 14+ (primary), Ubuntu 22.04+ via WSL2 or native Linux. Windows native is not supported — use WSL2.

# one-liner (macOS)
brew install imagemagick dssim ffmpeg && npm i -g agent-browser && curl -LsSf https://astral.sh/uv/install.sh | sh

# one-liner (Linux / WSL2)
sudo apt install -y ffmpeg imagemagick && cargo install dssim && npm i -g agent-browser && curl -LsSf https://astral.sh/uv/install.sh | sh
Individual install commands + verification
npm i -g agent-browser       # browser automation for AI agents (github.com/vercel-labs/agent-browser)
brew install imagemagick     # AE pixel comparison (apt: imagemagick, choco: imagemagick)
brew install dssim           # structural visual similarity (cargo install dssim)
brew install ffmpeg          # video capture + frame extraction (apt: ffmpeg, choco: ffmpeg)
curl -LsSf https://astral.sh/uv/install.sh | sh  # Python package manager (gate/hook system)

# verify
agent-browser --version
magick --version             # ImageMagick 7 (or: convert --version for v6)
dssim --help
ffmpeg -version
uv --version
python3 --version            # 3.11+ required (macOS default is sufficient)

uv auto-creates a virtualenv and installs scikit-image + Pillow on first run — no manual pip install needed.

Installation

# one-shot installer (deps + plugin marketplace registration)
curl -LsSf https://raw.githubusercontent.com/voidmatcha/ui-clone-skills/main/install.sh | bash

The installer is idempotent — it skips anything already installed and clones the repo to ~/.local/share/ui-clone-skills (override with INSTALL_DIR=...). It bootstraps uv, ffmpeg, imagemagick, dssim, and agent-browser, then registers the local checkout as a Claude Code marketplace.

After it finishes, run inside Claude Code:

/plugin install ui-clone-skills@voidmatcha
Manual install / alternatives
# clone + run installer locally
git clone https://github.com/voidmatcha/ui-clone-skills.git
cd ui-clone-skills
./install.sh                    # all flags: ./install.sh --help

# skip system deps (already installed):
./install.sh --no-deps

# skip marketplace registration (deps only):
./install.sh --no-marketplace

# npx skills (skills only — no marketplace registration, no deps)
# WARNING: this path skips system tooling (agent-browser, ffmpeg, imagemagick, dssim, uv)
# and the ui_clone/ Python package. Each SKILL.md opens with a preflight that detects
# the gap and tells the agent to surface the bootstrap one-liner above. Recommended
# when you want skills only and are wiring deps + python package yourself.
npx skills add voidmatcha/ui-clone-skills

Pipeline hooks (automatic)

Hooks register automatically via hooks/hooks.json on plugin install — no manual setup needed. All hooks route through a single hooks/shim.sh that fast-skips when no tmp/ref/ directory exists.

Hook module Event Purpose
ui_clone.hooks.pre_generate PreToolUse (Write/Edit) Blocks component writes until extraction completes. Creates .ui-re-active on first passing gate (activation site for the rest of the chain). Demotes state + invalidates sections/result.txt on post-done component edits
ui_clone.hooks.pre_bash PreToolUse (Bash) Two checks. (1) Blocks declaration-of-done bash commands (git commit, git push, gh pr create/merge/close) when verification is incomplete. (2) Blocks Bash redirects/streams that write to component files (cat > Foo.tsx, tee Foo.tsx, sed -i ... Foo.tsx) when extraction is incomplete — symmetrical with the Edit/Write gate so shell-redirect bypass is closed. Read-only commands pass through. Bypass: UI_RE_SKIP_BASH_GATE=1
ui_clone.hooks.post_verify PostToolUse (Bash) Warns on completion signals if verification hasn't run
ui_clone.hooks.devtools_errors PostToolUse (Bash) Checks browser devtools for console errors after each Bash call
ui_clone.hooks.section_gate Stop Blocks finishing if the current gate hasn't passed. Marker persists past section-compare; current_gate == "done" is the canonical complete signal
ui_clone.hooks.session_resume SessionStart, PostCompact Reinjects the verification checklist into context after a session resume or context compact (empirical: 73% of past verification skips happened within 20 min of a compact_boundary). Skipped when state is done

Gate system (Python)

The ui_clone/ package (Python 3.11+, managed by uv) provides pipeline gates, dependency tracking (DAG-based staleness detection), multiscale SSIM comparison, and viewport-relative CSS severity scoring.

# Gate validation
python -m ui_clone.gate <ref-dir> <gate> [--json]
# Gates: reference | extraction | bundle | spec | pre-generate | post-implement | section-compare | all
# Exit:  0=PASS  1=BLOCKED  2=usage error

# Pipeline status
python -m ui_clone.pipeline <url> <component> <session> status [--json]

Quickstart

After installing (see Installation), give Claude a URL and a target:

Clone the hero section from https://stripe.com/payments into React + Tailwind. Output to ./out/

The pipeline runs automatically. python -m ui_clone.pipeline detects the current phase and prints the next action; you don't invoke phases manually.

What happens:

  1. Reference capture → tmp/ref/payments-hero/{full,desktop,tablet,mobile}.png + scroll video
  2. DOM/CSS/JS extraction → tmp/ref/payments-hero/{structure,styles,assets}.json + transition-spec.json
  3. Component generation → ./out/PaymentsHero.tsx (CSS-first, original class names)
  4. Visual verification → auto-verify.sh → D0 layout health + AE/SSIM diff

If verification fails, the pipeline iterates up to 3 rounds (Phase H self-healing loop) before asking for human review.

Hooks are already registered on install via hooks/hooks.json — they block premature writes and warn on unverified completion signals automatically.


ui-reverse-engineering — Website → React Component

Turns any live website into a React + Tailwind component. For URL input, extracts real values. Screenshot and video inputs fall back to Claude Vision approximation.

Usage:

Clone this site: https://example.com
Copy the hero section from https://example.com
Replicate this UI (attach screenshot)
Turn this screen recording into a working component

Pipeline:

0.   Load existing analysis     — re-invoked? load transition-spec.json + bundle-map.json
R.   Capture reference         — static screenshots + scroll video
1.   Open & snapshot           — DOM tree, full-page screenshot. Session reuse for splash sites
W.   Webflow IX2 detection     — MANDATORY if <meta name=generator> contains "Webflow".
                                 Extract hide-rule selector list + IX2 timeline JSON.
                                 ⛔ gate: webflow-detection.json, webflow-hide-rule.json, webflow-ix2.json
2.   Extract structure         — HTML hierarchy, component boundaries, hidden elements
2.5  Extract assets            — CSS files, fonts, images, SVGs, videos, head metadata
2.5b SVG-as-text detection     — find headings rendered as SVG <path> not fonts → svg-text-elements.json
2.6p Dual-snapshot (splash)    — pre/post-splash DOM state → dom-state-diff.json.
                                 Auto-detects splash completion (no hardcoded waits)
2.6  Catalog init styles       — GSAP-baked inline styles, state coupling
3.   Extract styles            — computed CSS, design tokens, em-conversion (viewport-scaled).
                                 Merge runtime-injected transitions from dual-snapshot diff
4.   Detect responsive         — 2-pass viewport sweep + multi-viewport sizing → sizing-expressions.json
5.   Detect interactions       — hover/click/scroll. Extract ALL :hover CSS from live stylesheets
                                 (incl. inline <style>). data-text attribute scan. Hover video recording.
                                 JS hover timing + child cascade
5b.  Capture C3 (deferred)     — interaction/transition videos using selectors from Step 5
5c.  Bundle analysis           — ALL loaded chunks, scroll engine, hover event listeners. ⛔ gate: bundle
5d.  Transition spec           — transition-spec.json + bundle-map.json. ⛔ gate: spec
5e.  Capture verification      — record original, extract frames, verify spec spatial values
6.   Detect animations         — Phase A idle / B scroll (wheel events for smooth scroll) / C per-element
6b.  Assemble extracted.json
6c.  Pre-generation audit      — 6-stage design audit
6d.  Transition coverage       — multi-position scroll measurement → transition-coverage.json.
                                 Samples 10 scroll positions, decodes every transform matrix,
                                 classifies scroll-driven vs enter-reveal vs static. ⛔ gate: pre-generate
                                 (requires transition-coverage.json with animatedElements.length > 0)
7.   Generate component        — CSS-First + body scoping + CSS value diff verification.
                                 SVG-as-text verbatim, RAF parallax for smooth scroll
8.   Visual verification       — auto-verify.sh. ⛔ gate: post-implement
                                 (checks hover rule count, px fontSize leaks, scroll listeners)
8b.  Section comparison        — section-compare.sh (visual-debug/scripts/) crops each section independently → AE + structure diff.
                                 MANDATORY — replaces noisy full-page scroll comparison
8c.  Transition comparison     — transition-compare.sh idle/hover state + timing + computedStyle diff
9.   Interaction verification  — dispatch mouseenter for JS hovers, verify hover-css-rules match

Automation scripts (scripts/):

Script Purpose
auto-verify.sh Single-command verification: D0 layout health → Phase C scroll AE → post-implement gate
extract-assets.sh Downloads video backgrounds, Typekit fonts, CDN fonts. Extracts video poster frames
extract-section-html.sh Per-section HTML + computed CSS + media element extraction
download-chunks.sh Downloads ALL loaded chunks, detects animation libs, produces skeleton bundle-map.json
gsap-to-css.sh GSAP easing → CSS cubic-bezier (lookup, full table, or bundle scan)
extract-dynamic-styles.sh Classifies GSAP inline styles: layout (keep) vs animation (remove)
freeze-animations.sh Freeze CSS animations, JS timers, canvas, Lottie before screenshot capture
video-transition-compare.sh Video-based transition comparison: records same interaction on orig + impl, extracts frames at 60fps, runs SSIM batch diff

Visual comparison scripts (skills/visual-debug/scripts/):

Script Purpose
stray-absolute-check.sh Run first (Step 0 Structural) — single-URL detector for stray position: absolute elements with no positioned ancestor (Root Cause H — "footer disappeared" bug class). Often manifests only on shorter viewports
computed-diff.sh Run first — per-selector getComputedStyle diff. Finds fontWeight/display/height root causes before pixel diff. IGNORE_FONT_SIZE=1 skips fontSize/lineHeight/width/height (use on macOS with 105% system text scaling)
auto-diagnose.sh Second call — locates which element on the AE diff image is wrong by clustering hotspot pixels and resolving each cluster to the impl element underneath. Detects and hides full-viewport preloader overlays (heuristic: fixed, z-index ≥ 1000, ≥ 80% viewport coverage) before probing. For section-crop diffs, also hides fixed/sticky overlays so the probe sees the section content. Cheaper than tree-diff.sh
ae-compare.sh Single-pair AE pixel comparison primitive (used by other scripts; can be invoked directly for one-off ref/impl pairs)
batch-scroll.sh Captures scroll-position screenshots on both ref and impl at fixed percentages. Auto-detects Lenis / locomotive-scroll / body { overflow: hidden } inner-wrapper sites and falls back to wrapper.scrollTop + dispatched scroll event
tree-diff.sh Exhaustive per-element computed-style diff. Walks every visible impl element ≥ MIN_SIZE px, pairs with ref via elementFromPoint. Catches mismatches AE misses (wrong font rendering identically, same-box different overrides)
layout-health-check.sh D0: section height/total height comparison before pixel-level diff
layout-diff.sh Structural section bounding-box comparison between two URLs
layout-tree-diff.sh Geometry diff via signature-based pairing (text + tag + class hash + size class). Reports top/left/w/h deltas regardless of where elements moved. Catches "right element, wrong position" bugs
batch-compare.sh Batch AE comparison with dynamic-region threshold support
dssim-compare.sh Structural visual similarity (DSSIM) — catches layout issues AE misses
section-compare.sh Section-level visual + structural comparison (lazy pre-scroll for IntersectionObserver content, text fingerprint matching, per-section AE diff, DOM structure diff). Inner-scroll-container detection for Lenis/locomotive sites. NO_CANVAS=1 opt-in to hide <canvas> elements (WebGL/Three.js dynamic content drowns out structural diffs)
reveal-trigger-check.sh Run before transition-compare — runtime gate for the "stuck reveal" bug class. Enumerates initially-hidden elements (opacity 0 / non-identity transform), scrolls each into view, fails any whose style never advances. Reports the parent-chain overflow: hidden ancestor that's most likely clipping the IntersectionObserver
transition-spec-coverage.sh Static gate for spec-vs-impl coverage — parses transition-spec.json, greps the impl source for each entry's id / selector / type-derived hooks (RevealRise, useScrollTrigger, useScroll, etc.), FAILs if any entry has zero hits. Catches the failure class where hover transitions match while intersection/scroll-driven entries were never wired
transition-compare.sh Hover/transition behavior comparison (idle/hover state capture, computedStyle diff, timing validation). EXCLUDE_SELECTORS env var to skip third-party SDK overlays (default: cookie/consent banners). NO_CANVAS=1 opt-in to hide <canvas> elements during capture
hover-tree-diff.sh Per-element hover/transition diff. Captures idle → CDP :hover → settled style. Diffs timing (property/duration/easing/delay) + idle→hover delta. Uses CDP-level :hover (synthetic events do not fire :hover)
keyframes-diff.sh @keyframes declaration diff. Extracts keyframe rules from both pages; reports keyframes only on one side or same-name rules with different steps. Catches missing entrance animations and wrong timing curves baked into keyframes

Visual-debug scripts that open browser sessions support VIEW_W/VIEW_H env vars (default 1440x900) for custom viewport sizes.

Input modes:

Mode Quality When to use
URL (primary) Exact values Live site — getComputedStyle, real DOM, JS bundle
Screenshot Approximation (Claude Vision) Design mockup, inaccessible site
Video / recording Approximation (Claude Vision) Interactions visible in recording
Multiple screenshots Approximation (Claude Vision) Different pages or breakpoints

ui-capture — Visual Capture & Comparison

Captures baseline screenshots and transition videos. Standalone mode generates an overlay-based analysis report. Comparison mode generates a side-by-side page (original vs clone).

Classifies each effect by trigger type before recording — prevents blank videos from wrong activation methods.

Usage:

Capture the transitions from https://example.com
Record the hover effects on https://example.com
Compare https://example.com vs http://localhost:3000
Take a baseline of https://example.com before I start cloning

Pipeline:

Phase 1:  Full page capture        — section screenshots + full scroll video
                                     auto-detects custom scroll (Lenis, Locomotive)
Phase 2:  Transition detection     — classify all effects by trigger type → regions.json
Phase 2B-2E: Capture per trigger type:
  2B scroll-driven   — exploration video → clip screenshot before/mid/after
  2C css-hover       — eval + clip screenshot: idle + active
     js-class        — eval classList.add + clip screenshot: idle + active
     intersection    — eval classList.add + clip screenshot: before + after
  2D mousemove       — raster-path sweep video
  2E auto-timer      — passive recording for 2-3 cycles

local-url provided?
├── YES → Phase 3: Implementation capture
│         Phase 4A: Pixel-perfect gate (AE/SSIM + getComputedStyle)
│         Phase 4B: compare.html (side-by-side)
│         Phase 5:  User review
└── NO  → Phase R:  report.html (overlay-based analysis report)
          Phase 5:  User review

visual-debug — All Visual Verification in One Skill

The single source of truth for "is it done?" — covers automated AE/SSIM diff, pixel-perfect gating, self-healing fix loops, and VLM sanity checks in one place.

Two modes:

  • Quick comparisonauto-verify.sh runs D0 layout health check → batch-scroll capture → AE comparison → post-implement gate in one command. Zero vision tokens (AE/SSIM only, no LLM screenshot reads).
  • Full verificationverification.md with Phase A/B capture → Phase C comparison → Phase D0 layout health → Phase D pixel-perfect gate → Phase H self-healing loop → Phase E LLM review. Phase E reads a single diff image when something fails, so full verification does use vision tokens.

Token management

UI cloning sessions are token-intensive — DOM trees, computed styles, and JS bundles can blow through context fast. The plugin includes several built-in mitigations, plus integrates with external tools.

Built-in:

Strategy How
Zero vision tokens for verification AE/SSIM CLI tools diff screenshots. LLM only reads a single diff image on FAIL
Progressive-disclosure sub-docs SKILL.md ~6K tokens. 39 sub-docs load only when their step runs
Pipe-to-file rule Large eval output goes to tmp/ref/*.json, then Read/Grep specific lines
Single source of truth transition-spec.json produced once — implementation reads it, never re-greps bundles
Bash loop breaker After 10+ consecutive Bash calls, stop and analyze before continuing

External — rtk (Rust Token Killer):

rtk is a CLI proxy that intercepts shell commands (git status, ls, cat, etc.) and filters verbose output before it reaches the LLM. Saves 60–90% tokens on dev operations.

brew install rtk
rtk gain             # show token savings analytics

When installed alongside this plugin, rtk automatically reduces token cost of git, ls, find, and other shell commands issued during the pipeline. No configuration needed — Claude Code hooks rewrite commands transparently.

Security

All skills process untrusted external content (DOM, CSS, JS bundles, screenshots) from arbitrary URLs. Built-in mitigations:

  • Prompt injection defense — extracted data is wrapped in boundary markers and treated as display-only. All extraction sub-documents include explicit untrusted-data handling rules.
  • Post-extraction sanitization — automated scans for suspicious patterns (javascript:, eval(atob, prompt injection phrases) in extracted JSON.
  • Content boundary enforcementcomponent-generation.md never follows directives found in DOM text, HTML comments, CSS content properties, or data-* attributes.
  • Bundle safety — HTTPS-only, size-limited (10 MB), time-limited (30s), read-only (grep only, never executed).
  • No credential forwardingcurl sends no cookies or auth tokens.
  • Cleanuptmp/ref/ (may contain PII-bearing screenshots) is removed after verification.

See each skill's SKILL.md for full details.

Responsible use

This tool downloads and reproduces CSS, fonts, images, and design patterns from third-party websites. Users are responsible for:

  • Copyright — CSS, fonts, images, and SVGs are copyrightable. Use for learning, prototyping, or internal tools. Do not ship cloned designs as your own product without permission.
  • Terms of Service — Many sites prohibit automated scraping or reproduction. Check the target site's ToS before cloning.
  • Font licensing — Downloaded fonts (Typekit, Google Fonts, CDN) have their own licenses. Verify your usage rights before including them in production.
  • Trademarks — Logos, brand names, and distinctive design elements may be trademarked. Do not reproduce these for commercial use.

When NOT to use this tool:

  • Cloning a competitor's site for commercial deployment
  • Reproducing copyrighted designs without authorization
  • Bypassing paywalled or authenticated content

Intended use cases:

  • Learning how a site is built (CSS architecture, animation techniques)
  • Rapid prototyping with a reference design (to be restyled before shipping)
  • Rebuilding your own site from a previous version
  • Internal tools and demos

Evals

All skills include eval suites following skill-creator conventions, at skills/*/evals/.

Changelog

See CHANGELOG.md.

License

Apache-2.0. See LICENSE.txt.

Releases

No releases published

Packages

 
 
 

Contributors