prism-design
v2.17.0
Published
Refract any website into its real design system — computed CSS, screenshots, narrative DESIGN.md — in 90 seconds. The verifiable alternative to manually-written design docs.
Maintainers
Readme
Prism
Refract any website into its real design system — computed CSS, screenshots, and a narrative
DESIGN.md— then see exactly where the extraction is faithful and where it isn't.
🌐 Live catalog: https://prism.ps-tools.dev/
Prism reads the computed CSS of any public website — not the raw stylesheets, but what the browser actually renders — and turns it into a structured DESIGN.md in the Google DESIGN.md format that AI coding agents (Claude Code / Cursor / Bolt) consume natively, plus tokens.json, full screenshots, and a raw-CSS audit trail.
What makes it different isn't that it produces a DESIGN.md — that format is now an open Google standard and several tools generate it. It's that Prism is built to be verifiable and honest: every token is traced to a rendered CSS value, and it ships a Known Gaps section telling you what it could not reliably capture (CSS-in-JS runtimes, DRM fonts, Canvas/WebGL). No tool in this space tells you where it falls short. Prism does.
Playwright + TypeScript. MIT, local-first, no API keys, no accounts, no $39 per brand.
⚡ Prism vs getdesign.md
getdesign.md (VoltAgent, ~86k★) proved the category and owns the mindshare. Respect. But it's a hand-curated, manually-written, frozen catalog. Prism plays a different game: automated, re-extractable, and verifiable.
| | getdesign.md | Prism |
|---|---|---|
| Brands | 73 hand-curated | 77 pre-extracted · unlimited new (any public URL) |
| Source of truth | Manually written descriptions | getComputedStyle() — what the browser renders |
| Proof shipped | None | Desktop + mobile screenshots + raw-css.json |
| Re-extract when a site changes | ❌ frozen file | ✅ prism extract again → token diff |
| Honesty about quality | — | Known Gaps section + fidelity score per page |
| Format | DESIGN.md | DESIGN.md (Google spec) + tokens.json + raw-css.json |
| Price | $39/brand for custom | Free, MIT, end-to-end |
We do not claim to clone more faithfully than getdesign. On hand-written editorial nuance, a human still wins. Prism's edge is automation + verifiability + honesty — the axes a manual catalog structurally can't cover.
vs the OSS engines (dembrandt, designDNA)
The format is now a Google open standard, so "produces a DESIGN.md" is table stakes. What's left is proof and honesty — and that's where Prism is alone:
| | dembrandt (OSS) | designDNA (OSS) | Prism | |---|---|---|---| | Method | Playwright → computed CSS | infers from a screenshot | computed CSS + measured rebuild | | Fidelity score | ❌ | ❌ | ✅ SSIM + flat-area, fold & full-page, published | | Screenshots + raw CSS shipped | partial | ❌ | ✅ + public /compare pages | | Known Gaps / confidence | ❌ | ❌ | ✅ every DESIGN.md |
designDNA infers your design from an image; Prism measures it from the rendered DOM — then rebuilds the page and publishes how close it got, including where it falls short. dembrandt shares the engine but ships no score and no proof. The moat isn't the extractor — it's the verifiable, dated, reproducible honesty layer on top.
Quick start
npm install -g prism-design # the CLI binary is `prism`
npx playwright install chromium # one-time ~150MB download (needed to extract)The bare name
prismwas already taken on npm, so the package ships asprism-design; the command it installs isprism. Browsing the pre-extracted catalog needs no Playwright.
From source
The full TypeScript source ships inside the npm package (MIT) — no clone needed.
After npm install -g prism-design, the pipeline lives in your global
node_modules/prism-design/ (scripts/, bin/, mcp/). Edit there to hack on it.
Browse the catalog (no Playwright needed)
prism list # Browse the pre-extracted brand catalog
prism add linear.app # Copy Linear's DESIGN.md + tokens.json into ./
prism search dark # Find brands by keywordThen tell your agent: "Use DESIGN.md as the design reference before writing any UI."
Extract any URL
prism extract https://yoursite.com
# or, without npm link:
npx tsx scripts/clone.ts https://yoursite.comOutput lands in extractions/<domain>/:
DESIGN.md— 24-section narrative in the Google DESIGN.md format (Visual Theme, Colors, Typography, Components + state matrix, Layout, Motion, Depth, Do's/Don'ts, Responsive, Agent Prompt Guide, raw token export, Known Gaps & Confidence…)tokens.json— normalized design tokens (semantic palette from CSS custom properties)raw-css.json— fullgetComputedStyle()dump (ground truth, audit-friendly)screenshots/— desktop 1440px + mobile 390pxoutput/+ fidelity score — a rebuilt clone screenshotted and pixel-matched against the original (see Measured fidelity)
Extract from a Figma file
Point Prism at a Figma file URL and it reads the design through the Figma REST API — the source of truth (exact fills, text styles, effects, auto-layout spacing), not a rendered screenshot. Strictly more accurate than getComputedStyle(): it's the designer's intent, not the browser's approximation.
prism figma "https://www.figma.com/design/<key>/<name>?node-id=1-2"
# full DESIGN.md pipeline (extract → tokenize → narrative → showcase):
npx tsx scripts/clone.ts "https://www.figma.com/design/<key>/<name>"First set a token: FIGMA_TOKEN=... in .env (Figma → Settings → Security → Personal access tokens; scope file_content:read, plus optional file_variables:read to turn Figma Variables straight into CSS custom properties). A ?node-id= in the URL extracts just that frame; without it Prism picks the largest top-level frame. Output lands in extractions/figma-<key>/ with the same DESIGN.md / tokens.json / raw-css.json shape as a URL extraction.
Measured fidelity (the honest part)
Prism rebuilds the page's real structure from the extraction — real page background, real header + nav, real hero (composition, heading text + measured font-size, CTA labels), and the real sequence of colour bands down the whole page to its real height — then scores it against the original screenshot with two reproducible numbers, for two regions:
- structure (SSIM) — local layout/contrast match. The honest fidelity headline.
- flat-area (pixelmatch) — background/fill match. High, but background-dominated on its own, so it can't tell a real clone from a palette re-skin. That's exactly why we report SSIM too.
| Site | Structure — fold | Structure — full-page | Flat-area (fold / full) | |------|-----:|-----:|-----:| | linear.app | 66 | 79 | 93 / 95 | | stripe.com | 68 | 74 | 76 / 72 | | airbnb.com | 53 | 70 | 78 / 84 | | getdesign.md | 37 | 59 | 82 / 93 |
The structural rebuild scores +16 to +32 on full-page structure vs a palette-only re-skin of the
same tokens (--mode=tokens) — that delta is the layout it actually reconstructs (header, hero, and
colour bands at the real page height), and SSIM is the number built to see it. SSIM is a strict floor:
media we don't fetch is rendered as neutral placeholders and bands are flat colour, which caps it
honestly. Every DESIGN.md also ends with a Known Gaps section. Run it yourself:
npx tsx scripts/rebuild.ts <domain> # structural reconstruction (default) — or --mode=tokens
npx tsx scripts/compare.ts <domain> # structure (SSIM) + flat-area (pixelmatch) vs original
npx tsx scripts/compare-vs-gd-final.ts # score the DESIGN.md catalog vs getdesignWhat it actually captures
For any URL, via getComputedStyle() on every key element (body, header, nav, main, cards, buttons, inputs, headings…):
- Computed CSS values (the rendered truth, not the source stylesheet)
- CSS custom properties (700+ on Shopify-class sites, enabling faithful retheming)
- @keyframes animations with all frames, via a
document.styleSheetswalk - Pseudo-elements (
::before/::after), z-index stacking, transform 3D matrices - Grid layouts (
grid-template-*), container queries - Per-breakpoint snapshots at 360 / 768 / 1440px
- Font faces + OpenType features + variable axes
- Screenshots full-page, desktop + mobile
Anti-bot stealth for Cloudflare / DataDome:
npx tsx scripts/extract-block.ts https://protected-site.com "header" --stealthGeneration
- HTML self-contained (inline CSS, assets downloaded locally)
- React JSX (typed props) and Tailwind (utility + arbitrary values)
- Token retheming — apply one site's tokens onto another's structure (5 presets)
Architecture
scripts/
├── shared/ # Types, CSS helpers, named colors, logger
├── extractors/ # keyframes, pseudo, grid, container queries…
├── extract.ts # Main extraction pipeline (Playwright)
├── tokenize.ts # raw-css.json → normalized tokens.json
├── generate-design-md.ts # Narrative DESIGN.md (Google spec, 24 sections)
├── compare.ts # Visual diff (pixelmatch) — rebuilt clone vs original
├── compare-vs-gd-final.ts# Catalog scoring vs getdesign.md
├── bank.ts # Component bank CLI (register/query/stats/show)
├── bank-inject.ts # HTML/React/Tailwind code generation
├── generate-site.ts # Public catalog site generator
└── clone.ts # Top-level orchestrator (extract → tokenize → DESIGN.md → compare)Stats: ~24.5K LoC TypeScript, strict mode, 143 tests (npm test), tsc --noEmit clean.
Commands
# Pipeline
npx tsx scripts/clone.ts <URL> # Full pipeline (extract → tokenize → DESIGN.md → fidelity)
npx tsx scripts/extract.ts <URL> # Extraction only
npx tsx scripts/tokenize.ts <domain> # raw-css → tokens
npx tsx scripts/generate-design-md.ts <domain> # Narrative DESIGN.md
npx tsx scripts/compare.ts <domain> # Fidelity: rebuilt clone vs original (pixelmatch)
# Catalog / comparison
npx tsx scripts/compare-vs-gd-final.ts # Score catalog vs getdesign.md
npx tsx scripts/bank.ts diff <domain1> <domain2> # Token comparison between two sites
# Tests
npm test # 143 tests
npx tsc --noEmit # Type checkUse cases
Where Prism shines: design-system audits (extract N competitors, diff tokens), token migration from legacy sites to Tailwind, weekly UI veille (re-extract → diff), prototyping with a real reference's design language, teaching how pro sites structure CSS.
Where it doesn't fit: pixel-cloning CSS-in-JS SPAs (Linear, Notion), animation-heavy hero sites (Framer, 3D), anything behind an auth wall, content/copy extraction (we extract structure, not text).
Legal
Prism extracts publicly accessible CSS (no content, no proprietary code) — consistent with browser dev-tools usage. Respect robots.txt. Don't clone-and-deploy competitor sites. Commercially-licensed fonts (Typekit, Monotype) are detected but not downloaded — use your own licensed copies.
Credits
Built by Paul Sainton. The DESIGN.md format is a Google open standard (Apache 2.0). Inspired by getdesign.md (VoltAgent) and the Atareh "Clone Any Website with Claude Code" guide.
Stack: Playwright · playwright-extra · pixelmatch · pngjs · tsx.
License
MIT © Paul Sainton
