DESIGN.md is a file-format spec from Google Labs Code (the team behind Stitch) for handing your design system to a coding agent. YAML front matter holds the normative tokens; markdown body holds the rationale a designer would actually write. Lintable in CI, diffable across versions, exportable to Tailwind or DTCG. The bet is simple: DESIGN.md becomes a canonical filename agents recognise the way they already recognise README.md.
DESIGN.md is three things at once. It is a markdown file you commit to a repo. It is a format specification — a 14 KB document that defines exactly which YAML keys are allowed, which sections must appear, and what counts as a valid token reference. And it is an npm CLI, @google/design.md, that lints the file, diffs two versions, exports the tokens to Tailwind or to the DTCG tokens.json format, and prints the spec itself so it can be piped straight into an agent prompt.
The mental model is README.md for visual systems. README is the file every coding agent already loads to understand what a project does. DESIGN.md is the file an agent loads to understand what the project should look like. The point isn't that DESIGN.md is technically novel — YAML in front matter has existed forever, and design tokens are a solved problem at most shops. The point is the convention: a single filename, a fixed shape, a published spec, and a linter, so any agent reading the repo gets the same picture.
YAML front matter holds the normative data — palettes, typography scales, component tokens, layout dimensions. This is what tools and agents parse. Markdown body holds the rationale, the do's and don'ts, and the flavourful prose names ("Midnight Forest Green", "warm limestone") that designers actually use when they speak. The two layers are explicitly ranked: if the YAML and the prose disagree, the YAML wins. Tokens are the contract; prose is context.
The repo (google-labs-code/design.md) is roughly two weeks old at time of writing. ~7,300 GitHub stars and 26 open issues. Self-declared version: alpha. The README explicitly warns "expect changes to the format as it matures." The CLI, packaging, and CI scaffolding are stable. The format itself is not frozen. Treat any DESIGN.md you author today as something you'll likely need to migrate when 1.0 lands.
A DESIGN.md file has three layers: front matter (normative), body (rationale), and machine output (what the CLI exports). Same file feeds all three. To make this concrete, the example below is what know.2nth's own design system would look like rendered as a DESIGN.md.
--- name: know.2nth.ai version: 0.1.0 description: Knowledge portal and skills tree for 2nth.ai — dark-first, blue-and-sky on ink, technical without being cold. colors: primary: tokens: blue: "#2563EB" # action, focus, primary CTA blue-glow: "#3B82F6" # lighter primary, glows + halos sky: "#38BDF8" # secondary accent, links, labels sky-muted: "#7DD3FC" neutral: tokens: ink: "#0B1120" # page background (dark) ink-deep: "#060A14" # code block background navy: "#121D33" # raised surface paper: "#F8FAFC" # text on dark mist: "#E2E8F0" slate: "#94A3B8" # secondary text tertiary: tokens: warm: "#F59E0B" # amber, business / partner accent green: "#10B981" # security / open-tier accent violet: "#8B5CF6" # AI / ML domain accent rose: "#F43F5E" # professional services accent typography: families: sans: "Outfit, system-ui, -apple-system, sans-serif" mono: "'JetBrains Mono', monospace" weights: [300, 400, 500, 600, 700, 800] scale: label: { family: "{typography.families.mono}", size: "11px", weight: 500, tracking: "2px", transform: uppercase } body: { family: "{typography.families.sans}", size: "16px", weight: 300, leading: 1.75 } h1: { family: "{typography.families.sans}", size: "clamp(40px, 6vw, 66px)", weight: 800, tracking: "-2px" } h2: { family: "{typography.families.sans}", size: "clamp(26px, 3.4vw, 36px)", weight: 700, tracking: "-0.8px" } layout: containers: max: "1200px" read: "760px" spacing: { xs: "8px", sm: "12px", md: "20px", lg: "32px" } shapes: rounded: { sm: "8px", md: "12px", lg: "20px", full: "100px" } components: card: backgroundColor: "{colors.neutral.tokens.navy}" textColor: "{colors.neutral.tokens.paper}" rounded: "{shapes.rounded.lg}" padding: "{layout.spacing.lg}" button-primary: backgroundColor: "{colors.primary.tokens.blue}" textColor: "{colors.neutral.tokens.paper}" rounded: "{shapes.rounded.full}" button-primary-hover: backgroundColor: "{colors.primary.tokens.blue-glow}" textColor: "{colors.neutral.tokens.paper}" rounded: "{shapes.rounded.full}" --- # know.2nth.ai — design system ## Overview Dark-first knowledge portal. Blue-and-sky accents on a deep ink ground. Technical without being cold — structured monospace labels, generous fluid type, light theme as a first-class toggle. ## Colors The deep ink ({colors.neutral.tokens.ink}) is the canvas, navy ({colors.neutral.tokens.navy}) is the raised surface, blue and sky carry all the action. Tertiary accents are domain markers — warm for business, green for security, violet for AI, rose for professional services. ## Typography Outfit for prose at every weight from 300 to 800. JetBrains Mono for labels, code, paths, and anywhere a structural marker beats a flourish. Scale is fluid via clamp(); readers don't see the breakpoints. ## Do's and Don'ts - Do use {colors.primary.tokens.blue} for any interactive primary action. - Do use mono labels in section markers ("01 · What it is"). - Don't tint neutrals away from the published palette — light/dark theme switches use sibling tokens, not opacity tricks. - Don't ship a leaf that breaks the 9-section explainer pattern. Mid-page vibes are a regression to brochure thinking.
That whole thing parses. Drop the file at the root of any repo, run npx @google/design.md lint DESIGN.md, and the CLI tells you whether the YAML resolves, whether contrast meets WCAG AA, whether any token reference is broken, and whether the section order matches the spec. Run npx @google/design.md export --format dtcg and you get a DTCG-compliant tokens.json. Run npx @google/design.md spec --rules and the canonical 14 KB spec prints to stdout, ready to pipe into a Claude or Stitch prompt as context.
# Add to package.json scripts "design:lint": "design.md lint DESIGN.md", "design:diff": "design.md diff DESIGN.md origin/main:DESIGN.md", "design:tokens": "design.md export --format dtcg --out tokens.json", "design:tw": "design.md export --format tailwind --out tailwind.theme.js", "design:context": "design.md spec --rules" # pipe into agent
The format alone is just YAML conventions. The reason DESIGN.md earns its keep in CI is the seven lint rules — each fixed-severity, each opinionated, none of them configurable away. They turn "we have a token file" into "the token file is internally consistent and accessible by published rules". Skip the next section if you don't intend to lint; you'll get the file format without the value.
| Rule | Severity | What it catches |
|---|---|---|
broken-ref | Error | A token reference like {colors.primary.tokens.blue} that doesn't resolve. Typo, deleted token, restructured palette — CI fails. |
missing-primary | Warn | You declared colors: but didn't define a primary palette. The spec considers primary the only required palette. |
contrast-ratio | Warn | A component pair (backgroundColor + textColor) fails WCAG AA at 4.5:1. The only accessibility check baked in. |
orphaned-tokens | Warn | Tokens declared in palettes but never referenced by any component or alias. Dead colour. |
missing-typography | Warn | You haven't defined any typography scale entries. The spec assumes type is mandatory. |
section-order | Warn | Markdown headings out of canonical order (Overview, Colors, Typography, Layout, Elevation, Shapes, Components, Do's and Don'ts). |
token-summary | Info | Stats — counts of tokens by type, components by surface. Diagnostic, not gating. |
The format is deliberately small. That's a feature for shipping a spec quickly and a problem if you're expecting it to swallow your whole design system whole. Six places it bites.
Two weeks old, version 0.x, README says expect changes. Token reference syntax, section names, lint rules — any of it can shift. Pin a CLI version and budget a small migration when 1.0 lands.
The spec is conservative on colour. If your design system already uses OKLCH for perceptual uniformity, or wide-gamut P3 for premium displays, DESIGN.md downgrades you. There's no extension point for it yet.
Visual tokens and component-level styling. Animation, information architecture, microcopy, voice and tone are explicitly out of scope. The 2nth Design hub's motion.html, typography.html, and Imbila's voice system stay load-bearing.
Eight allowed component properties (backgroundColor, textColor, typography, rounded, padding, size, height, width). Hover/active/focus states are sibling components with naming conventions, not nested variants. Pragmatic, but a real divergence from how most design-token specs model state.
WCAG AA at 4.5:1 is baked in. AAA, focus-visible, motion-reduction, and every other accessibility concern lives outside the file. If you treat DESIGN.md as your accessibility surface, you're under-scoping the problem.
The whole bet is that coding agents start treating DESIGN.md as a canonical filename. Today, only Stitch (Google's design agent) does that natively. Claude Code, Cursor, Copilot don't — though piping design.md spec into the prompt makes it work. If your team isn't using an agent, the file is just YAML you could already have written.
DESIGN.md is the right tool when your design system needs to be legible to an agent, when you want a small format that fits in the prompt budget, and when you're willing to accept alpha-grade format churn in exchange for joining the convention early.
tokens.json.DESIGN.md is the design-side analogue of how 2nth already serves skill nodes to agents. The connections below are the ones worth holding in your head when deciding what role this format should play in a given build.
components: section is where a design system meets a component library.design.md export --format tailwind. The file becomes the source; the framework config becomes the artefact.The spec page on Stitch is the canonical reference. The GitHub repo is where the format actually evolves — track the issues if you're considering production use. Three worked examples ship in the repo.