design.md

CLI Tool

google-labs-code/design.md

A format specification for describing visual identity to coding agents.

Overview

Defines a format combining YAML front matter design tokens with Markdown prose for design rationale. Provides a CLI for linting and diffing DESIGN.md files, enabling structured design system persistence for coding agents.

README Preview

# DESIGN.md\n\nA format specification for describing a visual identity to coding agents. DESIGN.md gives agents a persistent, structured understanding of a design system.\n\n## The Format\n\nA DESIGN.md file combines machine-readable design tokens (YAML front matter) with human-readable design rationale (markdown prose). Tokens give agents exact values. Prose tells them *why* those values exist and how to apply them.\n\n```md\n---\nname: Heritage\ncolors:\n  primary: "#1A1C1E"\n  secondary: "#6C7278"\n  tertiary: "#B8422E"\n  neutral: "#F7F5F2"\ntypography:\n  h1:\n    fontFamily: Public Sans\n    fontSize: 3rem\n  body-md:\n    fontFamily: Public Sans\n    fontSize: 1rem\n  label-caps:\n    fontFamily: Space Grotesk\n    fontSize: 0.75rem\nrounded:\n  sm: 4px\n  md: 8px\nspacing:\n  sm: 8px\n  md: 16px\n---\n\n## Overview\n\nArchitectural Minimalism meets Journalistic Gravitas. The UI evokes a\npremium matte finish — a high-end broadsheet or contemporary gallery.\n\n## Colors\n\nThe palette is rooted in high-contrast neutrals and a single accent color.\n\n- **Primary (#1A1C1E):** Deep ink for headlines and core text.\n- **Secondary (#6C7278):** Sophisticated slate for borders, captions, metadata.\n- **Tertiary (#B8422E):** "Boston Clay" — the sole driver for interaction.\n- **Neutral (#F7F5F2):** Warm limestone foundation, softer than pure white.\n```\n\nAn agent that reads this file will produce a UI with deep ink headlines in Public Sans, a warm limestone background, and Boston Clay call-to-action buttons.\n\n## Getting Started\n\nValidate a DESIGN.md against the spec, catch broken token references, check WCAG contrast ratios, and surface structural findings — all as structured JSON that agents can act on.\n\n```bash\nnpx @google/design.md lint DESIGN.md\n```\n\n```json\n{\n  "findings": [\n    {\n      "severity": "warning",\n      "path": "components.button-primary",\n      "message": "textColor (#ffffff) on backgroundColor (#1A1C1E) has contrast ratio 15.42:1 

FAQ (5)

Troubleshooting
How do I fix the extra trailing newline in @google/design.md css-tailwind exports that fails git diff --check?

In @google/design.md@0.3.0, serializeTailwindV4() already appends one trailing newline, but the CLI uses console.log(), which adds another. Fix the exporter by replacing console.log(output) with process.stdout.write(output) for css-tailwind export output. Until a release containing the fix is available, normalize the generated file after export:

./node_modules/.bin/designmd export --format css-tailwind DESIGN.md \
  | perl -0pe 's/\n+\z/\n/' > out.css

Verify the file ends with exactly one newline:

python3 -c "from pathlib import Path; b=Path('out.css').read_bytes(); print(len(b)-len(b.rstrip(b'\\n')))"

The expected result is 1. This prevents strict whitespace checks such as git diff --check from failing on checked-in generated CSS.

GitHub Issue #139
how_to
How do I export design tokens from DESIGN.md as native CSS custom properties?

Use the css-vars export format:

npx @google/design.md export --format css-vars DESIGN.md > design.tokens.css

This generates a :root block containing CSS custom properties, for example:

:root {
  --color-primary: #1A1C1E;
  --spacing-md: 16px;
}

To add a namespace prefix to every variable, use --prefix:

npx @google/design.md export --format css-vars --prefix ds DESIGN.md > design.tokens.css

Dark-theme and media-query variants are not included in the initial implementation; support was added in PR #109.

GitHub Issue #15
informational
What is quantum computing in simple terms?

A regular computer uses bits that are either 1 (on) or 0 (off). A quantum computer uses qubits, which can exist in a combined state called superposition until the result is measured. This lets quantum computers explore many possibilities at once for certain complex calculations, though they are not simply faster versions of ordinary computers.

GitHub Issue #129
Troubleshooting
How do I fix "raw.match is not a function" when running @google/design.md lint?

This crash occurs in @google/design.md@0.2.0 when a spacing value in DESIGN.md is a YAML non-string value, such as unit: 8. Upgrade to v0.3.0, which includes the runtime type-guard fix. As a workaround, quote all dimension values:

spacing:
  unit: "8"
  "1": "4px"

Use unit: "8px" instead of unit: 8 or unit: 8px without quotes.

GitHub Issue #106
Troubleshooting
How do I make Color and Dimension type definitions data-driven from spec-config.yaml?

Upgrade to v0.4.0, where primitive types are rendered from spec-config.yaml. If applying the change manually, add a types section, for example:

types:
  Color:
    description: "A color value is any valid CSS color string."
    formats:
      - "Hex: #RGB, #RGBA, #RRGGBB, #RRGGBBAA"
      - "Named colors: red, cornflowerblue, transparent"
      - "Functional: rgb(), rgba(), hsl(), hsla(), hwb()"
      - "Wide-gamut: oklch(), oklab(), lch(), lab()"
      - "Mixing: color-mix(in srgb, ...)"
    note: "All color values are internally converted to sRGB for WCAG contrast checking."
  Dimension:
    description: "A dimension value is a string with a unit suffix."
    units: [px, em, rem]

Then remove the static Color and Dimension prose from spec.mdx and update the spec generator to iterate over types in spec-config.yaml, the same way it renders typography_properties. Run the spec-config and spec-generator tests to verify the output.

GitHub Issue #97