Extract design
Extract a complete design system — colors, typography, spacing, components, shadows, and W3C design tokens — from any live website using Dembrandt. Runs a headless browser against the URL and returns real computed values from the DOM. Use when you need a site's actual design tokens, want to reverse-engineer a visual design, or need to seed a design system from an existing product.From its SKILL.md
npx -y skills add dembrandt/dembrandt-skills --skill extract-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- runs commandsInstructs the agent to run 8 commands, including `npx -y dembrandt https://stripe.com` and 7 more.
SKILL.md
12.1 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
Extract Design — Dembrandt
Dembrandt runs a headless Chromium browser against any URL, walks up to thousands of DOM elements, reads computed CSS, and returns a structured design system: colors with confidence scoring, typography styles, spacing scale, border radius, borders, shadows, and interactive component styles.
How to Run
# Zero-install — npx fetches the package on first run (lowest friction)
npx -y dembrandt https://stripe.com
# Or install once (global), then call `dembrandt` directly
npm i -g dembrandt
# Basic extraction — outputs to terminal
dembrandt https://stripe.com
# JSON output — pipe into files or other tools
dembrandt https://stripe.com --json-only > stripe-tokens.json
# W3C DTCG format (design-tokens.org standard)
dembrandt https://stripe.com --dtcg --save-output
# Generate DESIGN.md (human + AI readable brand doc)
dembrandt https://stripe.com --design-md
# Multi-page crawl (follows internal links)
dembrandt https://stripe.com --crawl 5
# Dark mode colors
dembrandt https://stripe.com --dark-mode
# Mobile viewport
dembrandt https://stripe.com --mobile
# Everything saved to output/
dembrandt https://stripe.com --save-output
# Self-contained HTML report — open offline or attach as a CI artifact [dembrandt 0.19+]
dembrandt https://stripe.com --html report.html
# Drift gate — compare against a saved baseline; exits 1 on drift [dembrandt 0.19+]
dembrandt https://app.example.com --compare baseline.json --html report.html
MCP Usage (async by default)
To expose Dembrandt as MCP tools, add this server to the agent's MCP config (no install — npx fetches it on first run):
{ "mcpServers": { "dembrandt": { "command": "npx", "args": ["-y", "--package", "dembrandt", "dembrandt-mcp"] } } }
When using the Dembrandt MCP server, all extraction tools return a job_id immediately rather than blocking. Poll get_job_status until status is "completed":
1. get_design_tokens({ url: "stripe.com" })
→ { job_id: "job_123_abc", status: "queued" }
2. get_job_status({ job_id: "job_123_abc" })
→ { status: "running" } // poll again
3. get_job_status({ job_id: "job_123_abc" })
→ { status: "completed", result: { ... } }
Pass sync: true to any extraction tool to block and return the result directly (useful on fast networks, risks timeout on slow sites).
Extraction tools: get_design_tokens (everything), get_color_palette, get_typography, get_component_styles, get_surfaces, get_spacing, get_brand_identity. All accept slow, mobile (mobile viewport), and cookie (cookie string for authenticated pages); get_design_tokens and get_color_palette also accept darkMode and wcag (contrast analysis). [dembrandt 0.23.1+ for mobile/cookie/wcag]
Pure tools (no browser, synchronous, take an extraction object): compute_drift (0-100 drift score between two extractions), get_findings (design-system lint: contrast, consistency, duplication), export_dtcg (W3C Design Tokens format), generate_design_md (DESIGN.md brand guide), render_report (self-contained HTML report). Job control: get_job_status, list_jobs, cancel_job. [dembrandt 0.23.1+ for get_findings/export_dtcg/generate_design_md/list_jobs]
Note: dembrandt <=0.23.0 fails to start via the npx one-liner above (McpDepsMissingError) — the MCP SDK was an optional peer dependency. Fixed in 0.23.1; require it.
Output Structure
Dembrandt returns a structured object. The key sections:
colors.palette — Deduplicated colors with confidence (high/medium/low)
colors.semantic — Primary, secondary, background, text, and accent detection
colors.cssVariables — Named CSS custom properties with LCH + OKLCH values
typography.styles — Font family, size, weight, line-height per context
typography.sources — Google Fonts, Adobe Fonts, variable font detection
spacing.commonValues — Margin/padding scale with rem equivalents
spacing.scaleType — 4px, 8px, or custom grid
borderRadius.values — Border radius tokens with element context
borders.combinations — Width + style + color combinations
shadows — Box shadow elevation system
components.buttons — Button variants with hover/active/focus states
components.inputs — Input styles with focus states
components.links — Link colors and hover states
components.badges — Badge/tag/chip variants
breakpoints — Responsive breakpoints from CSS media queries
frameworks — Detected CSS framework (Tailwind, shadcn, MUI, etc.)
iconSystem — Detected icon library (Heroicons, FA, Material, etc.)
Working with Extracted Tokens
Seeding a Tailwind config
After extraction, map the output to tailwind.config.js:
// tailwind.config.js
export default {
theme: {
colors: {
primary: '#hex-from-colors.palette[0]',
// ...
},
fontFamily: {
sans: ['Family from typography.styles', 'system-ui'],
},
spacing: {
// Map spacing.commonValues px → rem
},
borderRadius: {
// Map borderRadius.values
},
boxShadow: {
// Map shadows
},
}
}
Seeding a shadcn/ui theme
Map semantic colors to shadcn CSS variables in HSL:
:root {
--background: /* from colors.semantic.background (0.22.0+), else colors.palette — lightest neutral */;
--foreground: /* from colors.semantic.text (0.22.0+), else colors.palette — darkest neutral */;
--primary: /* from colors.semantic.primary */;
--primary-foreground: /* contrasting color */;
--muted: /* mid-tone neutral */;
--border: /* from borders.combinations[0].color */;
--radius: /* from borderRadius.values[0].value */;
}
Reading confidence levels
Dembrandt scores every color by semantic context:
| Confidence | Meaning |
|---|---|
| high | Appears on semantically labeled elements (buttons, CTAs, headers with brand classes). Almost certainly a brand color. |
| medium | Moderate frequency or moderate context. Likely a brand color. |
| low | Rare, low semantic context. May be a one-off or component-specific color. |
Start with high confidence colors when building a palette. Include medium for full coverage. Treat low as reference only.
Flags Reference
| Flag | What it does |
|---|---|
--json-only | Clean JSON to stdout — pipe into files or tools |
--save-output | Save JSON to output/<domain>/<timestamp>.json |
--dtcg | W3C Design Tokens Community Group format |
--design-md | Generate DESIGN.md — prose-first brand doc |
--html [path] | Self-contained HTML report (inline CSS, embedded JSON). Open offline or attach as a CI artifact. (0.19+) |
--compare <baseline.json> | Diff against a saved extraction; prints a drift verdict and exits 1 on drift. CI gate. (0.19+) |
--brand-guide | Generate a PDF brand guide |
--dark-mode | Extract dark color scheme and merge into palette |
--mobile | Extract at 390px mobile viewport |
--crawl <n> | Crawl up to N pages and merge tokens |
--sitemap | Discover pages from sitemap.xml |
--slow | 3× timeouts — use on slow-loading or JS-heavy sites |
--screenshot <path> | Save a full-page screenshot |
--raw-colors | Include pre-filter raw colors in JSON output |
--browser firefox | Use Firefox instead of Chromium |
--stealth | Opt-in anti-detection: navigator spoofing + human mouse simulation. Use only when authorized. |
--user-agent <string> | Custom user agent string |
--locale <string> | Browser locale, e.g. fi-FI, en-GB (default: en-US) |
--timezone <string> | Browser timezone, e.g. Europe/Helsinki (default: America/New_York) |
--accept-language <string> | Custom Accept-Language header value |
--screen-size <WxH> | Physical screen resolution to report, e.g. 1920x1080 |
Drift Detection & CI (dembrandt 0.19+)
--compare turns extraction into a gate. Save a known-good baseline, then compare later extractions against it:
# 1. capture a baseline (in the SAME environment you will check against)
dembrandt https://app.example.com --json-only > baseline.json
# 2. later — compare; exits 0 if stable, 1 if drifted
dembrandt https://app.example.com --compare baseline.json --html report.html
- Runs the canonical drift engine over structured tokens — deterministic, not a pixel/render diff.
- Exit code:
0stable,1drift. Gates a pipeline directly. --htmlwrites a self-contained report; with--compareit includes a drift banner (added/removed/changed tokens). Attach it as a CI artifact.
Determinism: capture the baseline in the same environment you check it in (both production, or both the same preview). A baseline from one environment compared against another shows false drift.
In CI: run --compare <baseline> --html report.html against a preview/deployed URL, fail the job on exit 1, upload the HTML artifact. Programmatic: import computeDrift from dembrandt/drift and generateHtmlReport from dembrandt/report to diff and render server-side without the CLI.
Anti-Bot and SPA Handling
Dembrandt handles common extraction challenges automatically:
- SPA hydration — waits 8s for React/Vue/Svelte to render before extracting
- Lazy content — scrolls the full page to trigger lazy-loaded components
- Cloudflare / bot walls — auto-retries with a visible browser if headless is blocked
- Slow sites — use
--slowfor 3× timeouts on heavy JS bundles - Cookie banners — dismisses common CMP dialogs (OneTrust, cookielaw, GDPR patterns) automatically
- Bot detection bypass — use
--stealthto opt in to navigator spoofing and human mouse simulation; off by default so the tool identifies itself honestly
Checklist After Extraction
- Identify the 3–5 high-confidence colors — these are the core brand palette
- Check
colors.semantic.primary— is it correct? - Look at
typography.styles— what are the heading and body fonts? - Check
spacing.scaleType— 4px or 8px grid? - Review
components.buttons— how many variants exist? - Check
frameworks— is Tailwind, shadcn, or MUI detected? This shapes how you apply the tokens. - Use
--dark-modeif the site has a dark theme - Use
--crawl 3if the site has a multi-section design system spread across routes
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.