---
name: jpoindexter/design-system-governance
source: https://app.decimal.ai/s/jpoindexter-design-system-governance@1/SKILL.md
source_sha256: 1febdfedcafd
---

# Design System Governance & Operations

Governance is the difference between a component library and a design *system*. A library is a folder of components; a system is a product with users (your product teams), a roadmap, a release cadence, owners, and rules for change. This skill is the operating manual: how to structure ownership, run contribution, ship versions, keep design and code in sync, document, and measure adoption — without over-building before anyone uses it.

> **First principle.** A design system is infrastructure for *other people's* work. Every decision is graded by one question: does this make product teams ship faster, more consistently, and more accessibly? If a governance rule does not, cut it.

---

## 1. What a design system actually is

It is **not** a UI kit. It is the full stack below; skipping layers is the #1 reason systems stall.

| Layer | What it is | Lives in |
|---|---|---|
| **Principles** | The values that resolve arguments (e.g. "accessible by default", "boring on purpose") | Docs site, README |
| **Tokens** | Named design decisions — color, space, type, radius, motion, elevation | JSON source → Figma variables + code |
| **Components** | Coded, accessible, themeable UI primitives + their Figma equivalents | Code repo + Figma library |
| **Patterns** | Reusable compositions solving recurring problems (forms, empty states, data tables) | Docs + recipes |
| **Guidelines** | Content/voice, a11y, layout, do/don't usage rules | Docs |
| **Tooling** | Token pipeline, linters, CI, visual tests, release automation | Repo + CI |
| **People & process** | Owners, contribution model, intake, support, RFCs | This document |

**Maturity model** — diagnose honestly before choosing governance weight:

| Stage | Symptom | Governance need |
|---|---|---|
| **0 Chaos** | Every team reinvents buttons; 12 grays in prod | None yet — just inventory the drift |
| **1 Library** | Shared components exist, no tokens, no versioning | Add semver + a changelog |
| **2 Managed** | Tokens, docs, releases, an owner | Add contribution model + adoption tracking |
| **3 Integrated / Holistic** | Design↔code parity, tokens are single source of truth, adoption measured, multi-brand theming | Federated contribution, deprecation policy, ROI reporting |

Match governance to stage. A 3-person startup at Stage 1 does not need RFCs; a 200-engineer org at Stage 3 dies without them.

---

## 2. Operating models

Who owns and builds the system. Pick deliberately — the wrong model for your org size is a slow failure.

| Model | How it works | Best for | Failure mode |
|---|---|---|---|
| **Centralized (solitary)** | One dedicated team builds everything; product teams consume | < ~150 engineers, early systems | Becomes a bottleneck; backlog grows; teams fork in frustration |
| **Federated / distributed** | A small core curates; contributors come from product teams part-time | Large orgs, mature systems | Inconsistent quality, no clear ownership, "who decides?" paralysis |
| **Hybrid** | Small core team owns architecture, releases, quality bar + reviews; product teams contribute components under that bar | Most orgs past Stage 2 | Best default; needs a real contribution process or collapses to centralized |

**Team shape (hybrid core, minimum viable):** a **DS lead** (roadmap, stakeholders, funding), 1–2 **design-system designers** (Figma library, tokens, patterns), 2–3 **DS engineers** (component code, pipeline, CI), and **part-time contributors** from product. Even solo: separate the "system" hat from the "feature" hat explicitly.

**Funding & buy-in** — the silent killer. A system needs a budget line and an executive sponsor, or it is the first thing cut. Tactics: tie it to a top-down initiative (rebrand, a11y compliance, design-to-code velocity), show ROI early (§8), and never frame it as "the design team's side project."

**Top-down vs bottom-up.** Top-down (mandated, funded, sponsored) gets resources but risks building what teams don't want. Bottom-up (grassroots, proven by adoption) earns trust but starves for resources. The durable path is **bottom-up to prove value, then secure top-down funding** before the maintainers burn out. Watch for the classic trap: a system built by volunteers in their spare time that becomes load-bearing with no budget — that is a Stage-1 system with Stage-3 dependencies, and it fails the moment a volunteer leaves.

---

## 3. Documentation — docs-as-product

Undocumented components are not adopted; people copy-paste and fork. Docs are a product with its own UX.

**Per-component page (the canonical template):**

- **Anatomy** — labeled diagram of parts.
- **Usage** — when to use, when *not* to, and what to use instead.
- **Do / Don't** — visual pairs, not prose. The single highest-leverage doc artifact.
- **Props / API** — every prop, type, default, required flag — auto-generated from source, never hand-maintained.
- **Variants & states** — default, hover, focus, disabled, error, loading.
- **Accessibility** — keyboard map, ARIA roles, focus order, contrast notes, screen-reader behavior.
- **Code + design together** — live interactive example, copy-paste snippet, link to the Figma component.
- **Content guidelines** — labels, capitalization, tone for this component.

**Site-level pages:** principles, getting started (install + first component in < 5 min), contribution guide, changelog, design tokens reference, accessibility statement, roadmap, support/contact.

| Tool | Strength | Watch out |
|---|---|---|
| **Storybook** | Lives next to code; stories = the source of truth; addons for a11y, interactions, visual tests | Needs effort to be *designer*-friendly |
| **zeroheight** | Designer-friendly, pulls from Figma + Storybook, great for guidelines | Another surface to keep in sync |
| **Supernova** | Token + docs pipeline, code connect | Heavier; tool lock-in risk |
| **Figma (pages)** | Where designers already are | Not a substitute for usage/a11y docs |

**Rule:** props and tokens are **generated**, prose is **authored**. Hand-maintained prop tables rot within one sprint.

---

## 4. Versioning & releases — treat it like an API

A design system is a public API for your org. Use **semver** with intent.

| Bump | Meaning | Examples |
|---|---|---|
| **Major (breaking)** | Consumers must change code | Removed prop, renamed component, changed default, token deleted |
| **Minor (feature)** | Additive, backward-compatible | New component, new optional prop, new token |
| **Patch** | Bug/visual fix, no API change | A11y fix, style correction, internal refactor |

**Core policies:**

- **Additive by default.** Add the new path before removing the old. Breaking changes are expensive for *every* consumer simultaneously — earn them.
- **Deprecation = mark → migrate → remove.** Never delete in one step. (1) Mark deprecated (console warn, doc banner, `@deprecated` JSDoc), (2) ship a migration path + guide, (3) remove only in the *next major* after a stated grace period.
- **Changelogs are user-facing.** Group by Added / Changed / Deprecated / Removed / Fixed. Every breaking change gets a "how to migrate" line. Automate via conventional commits + `semantic-release`/Changesets so the changelog can't drift from reality.
- **Codemods for big breaks.** If a rename touches 50 call sites, ship a codemod (jscodeshift/ast-grep). The migration *guide* tells humans; the *codemod* does the work.
- **Cadence + canary.** Predictable releases (e.g. minor every 2 weeks, majors quarterly with a migration window). Ship a `next`/canary tag so teams can test ahead of a stable major.

> **Conventional commits → automated release** is the modern default: `feat:` → minor, `fix:` → patch, `feat!:`/`BREAKING CHANGE:` → major. The tool computes the version, tag, and changelog. No human guesses the number.

---

## 5. Figma structure & hygiene

Figma is the design source of truth and must be governed as strictly as the code repo.

- **Library files** — one (or a few) *published* libraries, separate from product files. Product files *consume*, never define.
- **Components, variants, properties** — one component, variants for state/size/type, component properties (boolean/text/instance-swap) instead of dozens of separate components. A button is one component with properties, not 40 frames.
- **Variables + modes** — tokens live as Figma **variables**; **modes** drive theming (light/dark, brand A/B, density). This is the Figma half of design↔code token parity.
- **Naming conventions** — match token names to code 1:1 (`color/bg/surface`, `space/200`). Slash-grouping organizes the panel. Divergent names between Figma and code is the parity gap in disguise.
- **Branching** — use Figma branches for library changes; review and merge like code. No edits to `main` library without review.
- **Linting / audits** — run detached-style and hardcoded-value audits (Design Lint, or the Figma API). Track **detach rate** as a hygiene metric. Sweep for orphan components, duplicate styles, and off-token colors regularly.

---

## 6. Design ↔ code parity — tokens are the bridge

The "design system gap" is the drift between what's in Figma and what ships. **Tokens** close it: one source of truth, transformed to every target.

```
tokens.json (source of truth, W3C DTCG format)
      │  Style Dictionary / Tokens Studio
      ├──▶ CSS variables / Tailwind theme / JS  (code)
      ├──▶ iOS / Android resources               (native)
      └──▶ Figma variables (via Tokens Studio sync) (design)
```

- **Single source of truth = the token JSON**, not Figma and not CSS. Both are *outputs*. Pick the source, generate the rest.
- **Three token tiers:** *primitive* (`blue-500`, `space-4`) → *semantic* (`color-action`, `space-inset-md`) → *component* (`button-bg`). Product code and Figma consume **semantic/component** tokens, never primitives. Re-theming = swap the semantic layer.
- **Style Dictionary** (or Tokens Studio + transforms) builds platform outputs from one JSON. **Tokens Studio** syncs that JSON ↔ Figma variables so designers and engineers share names.
- **Visual regression = the enforcement layer.** **Chromatic** (or Playwright/Loki) snapshots every Storybook story per PR and flags pixel diffs. This catches the drift that code review misses and is non-negotiable past Stage 2.
- **Code Connect** (Figma) links a Figma component to its real code snippet, so designers hand off the *actual* API.

**Theming & multi-brand** (when a second consumer actually exists — not before): theming is a *token* concern, never a component fork. Each component reads semantic tokens; a theme is a set of token *values*; a brand or mode is a swap of that set. In Figma this is **modes** on variables; in code it is a CSS-variable scope or theme object. Add density and dark mode the same way — as modes, not forks. The test of a good token architecture: shipping a new brand touches **zero component code**, only the semantic token layer.

---

## 7. Contribution model

Without a defined path, contributions are either rejected (teams fork) or merged carelessly (quality erodes). Define the funnel.

**Intake → promotion funnel:**

1. **Intake / proposal** — a lightweight issue template: problem, who needs it, evidence of recurrence, screenshots. Not every request becomes a component.
2. **Rule of 3 (promotion gate).** A pattern earns a place only after **3 real, distinct uses**. Before that it lives as a local one-off. This single rule prevents the snowflake-component explosion. Track: one-off → documented pattern → promoted component.
3. **RFC for anything cross-cutting** — new token category, breaking API, new pattern, theming model. A one-page written proposal (problem, proposed change, alternatives considered, blast radius on existing consumers, reversibility), a fixed comment period (e.g. 1 week), and a **recorded decision** with rationale. The RFC trail *is* your bus-factor insurance and your "why is it like this?" answer six months later.
4. **Build + review** against the **Definition of Done**.
5. **Promotion** — merged, documented, versioned, announced in the changelog.

**Intake triage outcomes** — not every request is a yes: **accept** (meets Rule of 3, build it), **defer** (valid but < 3 uses → keep as a local one-off, revisit), **redirect** (already solvable with existing primitives — show how), **decline** (out of scope, against principles — say so with reasoning). Saying no with a reason is governance; saying yes to everything is how the surface area explodes.

**Definition of Done (quality bar — a component is not "done" until all true):**

- [ ] Accessible: keyboard, focus, ARIA, contrast verified (axe + manual SR pass)
- [ ] Themeable: consumes semantic tokens, no hardcoded values
- [ ] All states: default/hover/focus/active/disabled/error/loading
- [ ] Responsive + RTL-safe
- [ ] Tested: unit + visual snapshot + a11y in CI
- [ ] Documented: usage, do/don't, props (generated), a11y notes
- [ ] Figma component published with matching name + properties
- [ ] Changelog entry + correct semver bump

**Support cadence:** weekly **office hours**, a public channel, and triaged issues. The core team's job is half building, half unblocking — budget for it.

---

## 8. Adoption & measurement

A system nobody uses is a cost center. Measure adoption or you can't defend the budget.

| Metric | What it tells you | Target direction |
|---|---|---|
| **Adoption / coverage** | % of UI built from DS components (via code scan / Figma analytics) | ↑ |
| **Detach rate** (Figma) | How often designers break from the library | ↓ |
| **Component usage** | Which components are used / ignored | informs roadmap |
| **Duplication** | Count of non-DS one-off buttons/inputs in prod | ↓ |
| **Time-to-first-component** | Onboarding friction | ↓ |
| **Issue resolution time** | Is the core team a bottleneck? | ↓ |

**Driving adoption:** make the system the path of least resistance (great docs, easy install, codemods for migration), **evangelize** (demos, release notes, wins), **onboard** new hires through it, and actively **deprecate one-offs** (find non-DS components, file migration tickets). Adoption is a campaign, not a launch.

**ROI framing for stakeholders:** hours saved per feature (don't rebuild buttons), defects avoided (a11y/visual bugs caught once), faster onboarding, consistent brand. Translate to dollars/velocity — that's what funds next year.

---

## 9. Quality: accessibility, testing, performance

- **Accessibility is built-in, not a checklist at the end.** Every component ships keyboard-operable, focus-visible, ARIA-correct, AA-contrast. Bake `axe-core` + jest-axe into CI; do manual screen-reader passes on interactive components. A DS that ships inaccessible components multiplies the harm across every team.
- **Test pyramid:** many unit (logic, props), fewer integration (component interactions), a few E2E. Plus **visual regression** (Chromatic) and **a11y** (axe) as their own gates.
- **Linting:** ESLint + Stylelint; a custom lint to ban hardcoded colors/spacing (force token use). Figma-side: detached-style audits.
- **Performance budgets:** track bundle size per component; enforce tree-shaking (named exports, `sideEffects: false`); set a gzipped budget and fail CI on regression. A 200KB design system that every page imports is a tax on every product.
- **Drift audits:** periodically scan prod for color/type/spacing values not in the token set. Drift is entropy; audit it back to zero.

---

## 10. Anti-patterns & common mistakes

| Anti-pattern | Why it kills the system | Do instead |
|---|---|---|
| **"Build it and they'll come"** | No adoption plan → shelf-ware | Co-design with a pilot team; ship for one real consumer first |
| **No governance** | Inconsistent quality, no decisions, forks | Define ownership + contribution + DoD early |
| **No versioning** | Every change breaks consumers silently | Semver + changelog + deprecation policy from day one |
| **Design↔code drift** | Figma and prod disagree; trust evaporates | Tokens as single source; visual regression in CI |
| **Snowflake components** | One-offs explode the surface area | Rule of 3 before promotion; track one-offs |
| **No docs / undocumented** | Copy-paste forking, repeated questions | Docs-as-product; generated props; do/don't pairs |
| **Over-engineering before 3 uses** | Months building abstractions nobody needs | Ship the concrete thing; generalize on the 3rd use |
| **Centralized bottleneck** | Backlog grows, teams route around it | Move to hybrid/federated; enable contribution |
| **No adoption metrics** | Can't prove value → budget cut | Coverage + detach rate + ROI reporting |
| **Bus factor of 1** | One person leaves, system dies | Document decisions, share ownership, RFC trail |
| **Premature theming/multi-brand** | Complexity tax with no consumer | Add the second brand when the second brand exists |

---

## Quick reference — governance checklist

- [ ] Maturity stage diagnosed; governance weight matched to it
- [ ] Operating model chosen (default: **hybrid**); owner + sponsor named
- [ ] Tokens are the single source of truth → generated to code + Figma
- [ ] Semver + automated changelog + deprecation (mark→migrate→remove)
- [ ] Contribution funnel with **Rule of 3** + Definition of Done
- [ ] Docs-as-product: per-component anatomy/usage/do-don't/a11y/props
- [ ] CI gates: unit + visual regression + a11y + token-lint + bundle budget
- [ ] Figma governed: published libraries, variables+modes, naming = code, branch review
- [ ] Adoption measured (coverage, detach rate) and reported as ROI

> **The one rule that prevents most failures:** *additive by default, deprecate gracefully, and never promote a component until its third real use.* Everything else is scaffolding around that discipline.