brandmd

npm version DESIGN.md lint: clean License: MIT

Stop Claude Code, Cursor, and Gemini CLI from guessing your UI. brandmd extracts any website's design system into a spec-valid DESIGN.md that passes the official @google/design.md linter.

AI coding agents generate generic screens when they don't know your colors, fonts, spacing, components, and layout rules. Run one command, drop DESIGN.md in your project root, and your agent has brand context before it writes code. Output is the official DESIGN.md format: YAML frontmatter with machine-readable tokens plus canonical prose sections. Default extraction runs locally with no API key.

npx brandmd https://stripe.com -o DESIGN.md

Every generated DESIGN.md validates clean:

npx @google/design.md lint DESIGN.md   # 0 errors, 0 warnings

Pass multiple URLs to merge brand tokens across pages: npx brandmd https://site.com https://site.com/pricing https://site.com/docs -o DESIGN.md

Outputs to whatever your stack reads:

  • DESIGN.md (default): for Claude Code, Cursor, Gemini CLI, Codex, Stitch
  • --json: raw extracted tokens for scripts, MCP servers, and agent toolchains
  • --css: CSS custom properties, drop into any project
  • --tailwind: Tailwind v4 @theme block
  • --html: visual, shareable brand guide

Combine with:

  • --agent: also writes .cursor/rules/brand.mdc and SKILL.md to both .agents/skills/brand-style/ (the universal Agent Skills path used by skills.sh across 50+ agents) and .claude/skills/brand-style/ (backward-compat for direct Claude Code users). No manual wiring. Picked up automatically by Claude Code, Cursor, Codex, Gemini CLI, Kiro CLI, and the rest of the skills.sh ecosystem. Schema-compatible with Anthropic Claude Code Skills, google/skills, and vercel-labs/agent-skills.
  • --dark: also extract dark mode tokens
  • --vision: adds illustration style, photography mood, copywriting voice, and microcopy patterns from a screenshot. Requires GEMINI_API_KEY (free at aistudio.google.com/apikey).

Works as brand context for Claude Code, Cursor rules, Gemini CLI, Codex, Google Stitch, MCP servers, and any coding agent that reads markdown.

Real examples: Stripe · Linear · GitHub · Vercel · Notion · Cursor · Anthropic · Figma · Supabase · Raycast · +20 more in the gallery

---
version: alpha
name: Stripe
colors:
  primary: "#533afd"
  background: "#ffffff"
  on-background: "#0a2540"
typography:
  headline-lg:
    fontFamily: sohne-var
    fontSize: 48px
    fontWeight: 600
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
---

## Colors

- **Indigo** (`#533afd`): Accent background (accent)
- **White** (`#ffffff`): Page background (dominant)

## Typography

**Primary font:** sohne-var

The YAML frontmatter is the machine-readable token layer; the prose sections carry the evidence-based rationale (tiered palette, confidence tags, observed component styles). brandmd gives Claude Code, Cursor, Gemini CLI, and Codex real design context: it extracts a live website's colors, typography, spacing, shadows, component patterns, and layout rules, so AI coding agents build on-brand UI instead of generic screens.

Installable example skills repo

If you want ready-made brand skills without running brandmd yourself, install yuvrajangadsingh/brand-skills directly:

npx skills add yuvrajangadsingh/brand-skills

That installs 5 brandmd-generated skills (Tailwind CSS, shadcn/ui, Vercel, Mintlify, Anthropic) into your project's agent skills folder. Each skill is self-contained with a bundled references/DESIGN.md. Community examples generated from public marketing sites, not affiliated with the named brands.

  • v0.14: Spec + truth release. Emits the official DESIGN.md format (YAML frontmatter + canonical sections) that passes @google/design.md lint clean. Fail-closed refusals with a distinct exit code (--allow-blocked to override), atomic writes, gradient-stop parsing, honest CTA/button selection, shadow values in DESIGN.md, and a fixed generate/parse/diff round trip.
  • v0.13: Detects block / access-denied pages (Akamai, PerimeterX, WAF 403s) and warns instead of emitting a garbage design system. Notes when a site uses motion (canvas, WebGL, Lottie, rAF).
  • v0.12: Trust-repair: evidence-based visual character, tiered palette, HSL color naming, no more scientific-notation radii, clustered type scale.
  • v0.11: diff subcommand and the hosted example gallery.
  • v0.10: Universal .agents/ skills path.
  • v0.9: --agent flag writes Cursor rule + Claude Code skill alongside DESIGN.md. CI switched to npm Trusted Publishing.
  • v0.8: More accurate primary font detection across display, heading, body, and global text roles.
  • v0.7: Cloudflare-protected sites handled by waiting up to 20s for the JS challenge.
  • v0.6: Optional --vision adds illustration style, photography mood, copywriting voice, and microcopy notes. Requires a free Gemini API key.

See CHANGELOG.md for the full history.

Examples

See all 31 DESIGN.md examples in the gallery →

Flagship deep links (DESIGN.md):

Other output formats:

  • Vercel (CSS custom properties)
  • Linear (Tailwind v4 @theme)

Why

DESIGN.md is an open spec (Apache 2.0) for encoding a design system in a format LLMs can read: YAML frontmatter with typed tokens plus canonical prose sections. There's an official @google/design.md CLI that lints, diffs, and exports it. Problem is, nobody wants to write one from scratch.

brandmd does it from the terminal. Point it at any URL, get a spec-valid DESIGN.md back that passes @google/design.md lint clean. Drop it in your project root and your AI tools start generating on-brand UI.

Install

# Run directly (no install)
npx brandmd https://linear.app

# Install globally
npm i -g brandmd

# As an agent skill (Claude Code, Cursor, Gemini CLI, Copilot, Codex, 30+ platforms)
npx skills add yuvrajangadsingh/brandmd

Usage

# DESIGN.md (default)
brandmd https://stripe.com
brandmd https://stripe.com -o DESIGN.md

# Multiple pages (merges tokens)
brandmd https://stripe.com https://stripe.com/pricing https://stripe.com/docs

# Dark mode extraction
brandmd https://github.com --dark

# Vision: capture illustration style, photography mood, copywriting voice
# (CSS can't see these; Gemini reads the screenshot.)
export GEMINI_API_KEY=your-key-here  # free: https://aistudio.google.com/apikey
brandmd https://linear.app --vision
# Cloudflare-protected sites: brandmd waits up to 20s for the JS challenge
# to auto-resolve. If your site needs longer, pass --cf-wait-ms 30000.
# If the challenge persists, you'll get a clear error rather than garbage tokens.

# CSS custom properties
brandmd https://vercel.com --css

# Tailwind v4 @theme
brandmd https://linear.app --tailwind

# HTML brand guide (visual, shareable)
brandmd https://github.com --html

# Raw tokens as JSON
brandmd https://stripe.com --json

# Compare two extractions
brandmd diff examples/stripe.md examples/vercel.md --out BRAND_DIFF.md

Refusals and exit codes

brandmd fails closed. If a page is a bot-block / access-denied page, a login / sign-in wall landing, or too thin to describe (no rendered text, empty palette), it refuses in every format and writes no artifact, so a bad capture can't silently overwrite a good DESIGN.md. A plain cross-origin redirect (say marketing -> app on another domain) doesn't refuse: it warns on stderr and is flagged in the output's provenance block, per page.

Exit code Meaning
0 success
1 operational or validation error (bad URL, bad flag, browser launch failure)
2 refused: block page, insufficient evidence, or a login-wall landing

Pass --allow-blocked to force output anyway; the artifact carries a block marker in every format (Markdown callout, CSS/Tailwind comment header, HTML banner, JSON blockLikely). Writes are transactional (temp file + rename with rollback), including the --agent set and brandmd diff, so a partial failure never truncates an existing file. Atomicity is per process: concurrent brandmd runs against the same output directory are not coordinated, though collision-safe temp/backup names mean one run can never eat another's files.

Gallery

See 5 real DESIGN.md snapshots in the browser (Stripe, Vercel, Linear, Anthropic, Mintlify), or scan the examples/ folder for 30+ more. Each snapshot is generated from a single public page visit and is observed, not canonical.

Diff

brandmd diff examples/stripe.md examples/vercel.md --out BRAND_DIFF.md

Compares two DESIGN.md files and writes a markdown diff: shared and unique colors, typography table, spacing and radii table, per-component property diff, and a "what to copy / what to avoid" synthesis. Local files only in v0.11. See examples/diff-stripe-vs-vercel.md for the output format.

Output formats

DESIGN.md (default)

The official DESIGN.md format: YAML frontmatter (machine-readable colors, typography, rounded, spacing, components tokens) plus canonical sections (Overview, Colors, Typography, Layout, Elevation & Depth, Shapes, Components, Do's and Don'ts). Validates clean under @google/design.md lint. Drop it in your project root and AI coding agents use it to generate on-brand UI.

CSS custom properties (--css)

:root {
  --color-accents-1: #FAFAFA;
  --color-blue-600: #0075DE;
  --font-primary: "Geist";
  --space-1: 4px;
  --radius-sm: 4px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
}

Tailwind v4 (--tailwind)

@import "tailwindcss";

@theme {
  --color-primary: #0075DE;
  --font-sans: "Geist", system-ui, sans-serif;
  --spacing-1: 4px;
  --radius-sm: 4px;
}

HTML brand guide (--html)

A self-contained dark-themed HTML page with color swatches, font specimens, spacing visualization, and shadow examples. Open it in a browser or share it with stakeholders.

JSON (--json)

Raw extracted tokens for programmatic use.

Multi-page extraction

Pass multiple URLs to merge tokens from different pages into one DESIGN.md. Each page is normalized so long content pages don't dominate.

brandmd https://stripe.com https://stripe.com/pricing https://stripe.com/docs

Failed pages are skipped with a warning. Mixed domains show a warning.

Dark mode

Extract dark theme tokens as a separate section:

brandmd https://github.com --dark

Adds a "Dark Theme Overrides" section to the DESIGN.md with the dark color palette. Uses prefers-color-scheme: dark via Playwright, so it captures what users actually see in dark mode. Only affects DESIGN.md output (ignored for --css, --tailwind, --html).

What it extracts

  • CSS custom properties from :root and @media rules (uses actual variable names when available)
  • Colors with semantic roles (background, text, accent, border)
  • Typography with role-aware Primary detection (display > heading > body), per-role font breakdown, and a full "all detected fonts" frequency list. Skips monospace, default fallbacks, and icon fonts when picking Primary.
  • Spacing scale and base grid unit
  • Border radii and shadow styles
  • Component patterns (buttons, cards, inputs)

How it works

  1. Renders each page in a headless browser (Playwright)
  2. Scrolls through to trigger lazy-loaded content
  3. Dismisses cookie banners and overlays
  4. Extracts CSS custom properties from :root (recurses into @media rules)
  5. Extracts computed styles from every visible element
  6. Clusters similar colors, identifies the spacing scale
  7. Merges tokens across pages (normalized per page)
  8. Outputs in your chosen format

No LLM calls, no API keys, runs entirely on your machine.

Agent skill

brandmd ships as an Agent Skill that works across 30+ platforms including Claude Code, Cursor, VS Code/Copilot, Codex, and Gemini CLI.

npx skills add yuvrajangadsingh/brandmd

Then tell your agent: "extract the design system from https://linear.app"

If brandmd saved you time, consider starring the repo.

Built by Yuvraj Angad Singh. Also: vibecheck (catch AI-generated code smells) and vemb (embeddings from the command line). Follow on GitHub for new dev-tool experiments.

License

MIT