Design Engineering
Design & Architecture

Design System Governance

Evolve your design system without breaking products — token versioning, component deprecation, change logs, and patterns for managing systems across multiple products.

A design system that ships and stays frozen is worse than no design system at all — it becomes a constraint rather than an accelerator. Governance is the process for evolving the system intentionally: adding new tokens, deprecating old components, communicating changes, and managing the system across multiple products or teams.

Design engineers own this layer. Developers consume tokens and components. Product designers define the visual direction. You translate between them and keep the system healthy.

Why governance matters

Without governanceWith governance
Tokens multiply with slight variations (blue-500, blue-510, brand-blue)One canonical token per semantic role
Old components linger forever — nobody knows if they are safe to useDeprecated components have clear sunset timelines and migration paths
Breaking changes surprise consuming teamsBreaking changes are versioned, communicated, and released with migration guides
Two products using the same system diverge into incompatible forksShared core, product-specific layers, clear ownership boundaries
No one knows who decides what gets addedClear contribution process with design engineering review

Token versioning

Tokens are the most shared and most fragile part of the system. A colour change that fixes contrast on one component can break the visual hierarchy of another. Version tokens deliberately.

Semantic naming over value naming

Separate what a token represents from its current value. This lets you change the value without renaming the token everywhere:

/* Bad — value-named. Changing the hex means changing the name everywhere. */
--color-blue-500: #3b82f6;

/* Good — semantic. The hex can change independently of the name. */
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
--color-primary-foreground: #ffffff;

The token lifecycle

StageWhat it meansAction
ProposedA designer or engineer requests a new tokenOpen a proposal with: name, proposed value, where it will be used, which existing token it relates to
DraftAdded to the system in a feature branchAvailable for use in a single PR, reviewed before merge
ActiveMerged and available for all consumersDocumented in the token registry with usage examples
DeprecatedScheduled for removal, replacement existsConsumers see a warning. Migration path documented. Sunset date set.
RemovedDeleted from the systemOnly after 0 consumers remain for one release cycle

Token registry

Keep a single source of truth for every token in the system. This can be a JSON file, a Figma variables export, or a dedicated page in your docs. The format matters less than the discipline:

tokens/registry.json — condensed example
{
  "colors": {
    "primary": {
      "value": "#3b82f6",
      "status": "active",
      "added": "2025-01-15",
      "designToken": "color/primary/500",
      "tailwindClass": "bg-primary",
      "usedIn": ["Button", "Link", "Badge", "Input:focus-ring"]
    },
    "surface-muted": {
      "value": "#f1f5f9",
      "status": "deprecated",
      "replacedBy": "surface-secondary",
      "sunsetDate": "2025-09-01",
      "added": "2024-03-10"
    }
  }
}

The token registry should be machine-readable. AI agents and linting tools can consume it to enforce constraints — if a token is deprecated, the agent should not suggest it. See AI-Ready Design Systems for the schema agents need.

Component deprecation

Components age. Design patterns change. The system needs a clear process for retiring old components without breaking products that still use them.

Deprecation workflow

  1. Identify — a component no longer meets design standards, has an accessibility issue that cannot be fixed without a breaking change, or has been superseded
  2. Announce — add a deprecation notice to the component's documentation. Set a sunset date (typically 2–3 release cycles out)
  3. Provide migration path — document the replacement component, write a migration guide, and where possible provide a codemod
  4. Migrate consumers — track which products still use the deprecated component. Help teams migrate. Block new usage in code review
  5. Remove — once 0 consumers remain, delete the component

Deprecation notice pattern

Deprecated component with JSDoc warning
/**
 * @deprecated Use `ProjectCard` instead.
 * This component will be removed in v3.0 (2025-09-01).
 * Migration: replace `<LegacyProjectTile project={p} />` with `<ProjectCard project={p} />`.
 *
 * @see {@link ProjectCard}
 */
export function LegacyProjectTile({ project }: { project: Project }) {
  // ...
}

Tracking consumption

Before removing a component, know who uses it:

# Search the entire codebase for imports of a deprecated component
rg "LegacyProjectTile" --type tsx --type ts

# If using a monorepo, search across all packages
rg "LegacyProjectTile" packages/ apps/

Change communication

Every change to the system needs to reach the people who use it. The format should be lightweight but consistent.

Change log template

## 2025-06-01 — Design System v2.3

### Added
- `--color-success` token (replaces `--color-green-500`)
- `Select` component (primitive, accessible, keyboard-navigable)

### Changed
- `Button`: increased touch target to 44px minimum
- `--radius-md`: changed from 6px to 8px for visual consistency

### Deprecated
- `LegacyProjectTile` → use `ProjectCard` (sunset: 2025-09-01)
- `--color-green-500` → use `--color-success`

### Fixed
- `Dialog` focus trap no longer captures screen reader virtual cursor
- `Table` horizontal scroll visible on iOS Safari

### Breaking
- `Modal` `size` prop renamed to `width` (migration: find/replace `size=``width=`)

Multi-product systems

When one design system serves multiple products — a marketing site, a dashboard, a client-facing portal — you need product-specific layers without forking the system.

Layered architecture

┌─────────────────────────────────┐
│        Product Layer            │  ← Product-specific tokens & components
│   (Dashboard, Marketing, etc.)  │
├─────────────────────────────────┤
│        System Core              │  ← Shared tokens, primitives, utilities
│   (Colors, spacing, typography) │
└─────────────────────────────────┘

The core contains everything that is genuinely shared: colour palette, spacing scale, type scale, primitives like Button and Input. Product layers extend the core with product-specific components (DashboardChart, MarketingHero) and can override tokens where needed.

Ownership boundaries

LayerWho decidesWho can contribute
System CoreDesign engineering teamAnyone, with design engineering review
Product layerProduct team + design engineering consultProduct team, with PR review from design engineering

The core must stay small and genuinely shared. If a component is only used by one product, it belongs in that product's layer — not the core. Every core component is a commitment to maintain for every consumer.

Contribution workflow

The system should be open to contributions from designers and developers across the organisation while maintaining quality:

  1. Propose — open an issue or PR describing the addition or change. Include: rationale, visual examples, affected components
  2. Review — design engineering reviews for: token alignment, accessibility, responsive behaviour, and whether it belongs in core or a product layer
  3. Test — visual regression tests pass. Accessibility audit passes. No regressions in existing components
  4. Document — update the component docs, token registry, and change log
  5. Release — version the change. Communicate to consumers via the change log

On this page