Fixing missing-primary in DESIGN.md

The missing-primary rule fires with severity: warning when your colors section has at least one entry but none of them is named primary. The file is accepted (warnings do not fail the CLI), but downstream agents will auto-generate a primary color instead of using one you chose.

Why primary matters#

Agents that consume a DESIGN.md file treat the primary token as the anchor for the entire palette. When it is absent, the agent infers or auto-generates a primary color from the other tokens it finds (or from the prose description in the Markdown body). That inference is non-deterministic: the same DESIGN.md may produce different primary colors across agent runs, tool versions, or model updates. Defining primary explicitly pins the color and ensures reproducible output.

The rule is advisory (warning, not error) because a design system without a primary key is structurally valid. You can ship it. But the warning signals a likely oversight.

What triggers it#

The rule checks two conditions:

  1. The colors map has at least one entry (an empty colors: block does not trigger it).
  2. The map has no key whose name is exactly primary (case-sensitive).

Both conditions must hold for the warning to fire.

Example that trips the rule:

---
name: Mono Studio
colors:
  neutral: "#F5F5F5"
  accent: "#4A6FFF"
  error: "#CC2929"
---

## Colors

A light neutral surface with an electric-blue accent and a red error state.

No primary key is present. The linter emits:

{
  "severity": "warning",
  "path": "colors",
  "message": "No 'primary' color defined. The agent will auto-generate key colors, reducing your control over the palette."
}

How to fix#

Add a primary entry to the colors map. The value must be a # followed by exactly six hex digits (sRGB):

---
name: Mono Studio
colors:
  primary: "#111111"
  neutral: "#F5F5F5"
  accent: "#4A6FFF"
  error: "#CC2929"
---

## Colors

A near-black primary on a light neutral surface, with an electric-blue accent
for interactive elements and a red error state.

After this addition, re-run the linter:

npx @google/design.md lint DESIGN.md --format json

The missing-primary warning will no longer appear in the findings list.

Choosing a primary value#

The primary token is typically your main brand color: the color used on key UI surfaces, primary buttons, headlines, and high-emphasis icons. A few practical guidelines:

  • Near-black on light surfaces: #111111 or #1A1C1E give strong WCAG contrast against white backgrounds and component text colors.
  • Brand hue: If your brand has a specific hue (a blue, green, or warm tone), set primary to a mid-to-dark tint that passes contrast checks when paired with white text.
  • Consistency with components: If you define a button-primary component with backgroundColor: "{colors.primary}", pinning primary ensures the button always uses your intended color.

The primary key and other lint rules#

Defining primary interacts with two other rules:

  • orphaned-tokens: The primary family is one of seven Material Design 3 standard families that orphaned-tokens never flags, even when no component references it. You will not get an orphan warning for a primary token that sits unused.
  • contrast-ratio: If you use {colors.primary} as a backgroundColor or textColor in a component, the contrast-ratio rule will check the resulting pair. Make sure the pairing passes 4.5:1.

Companion tokens#

The spec recommends adding a semantic companion for primary when you have components that place text over it:

colors:
  primary: "#111111"
  on-primary: "#FFFFFF"

on-primary is the conventional name for the text/icon color placed on top of primary. Together they give the contrast-ratio rule both values it needs to check the pair automatically.


Try it in the tool

Was this page helpful?