---
title: "&quot;Design systems are a platform: treat them like one&quot; | Dhruv Doshi"
description: "Most design systems die the same way: a burst of initial energy produces a component library, teams adopt it unevenly, the library drifts from the product, contributions stall, and…"
canonical: https://doshidhruv.com/notes/design-systems-are-a-platform-treat-them-like-one/
author: Dhruv Doshi
---

[Skip to content](#main-content)

[Dhruv Doshi](/)

[Work](/projects)[Experience](/resume)[Notes](/notes)[Guides](/guides)[Research](/research)[Investing](/investing)[About](/about)[Contact](/contact)[Search /](/search)dark mode

[All notes](/notes)

[Frontend architecture](/topics/frontend-architecture)

# "Design systems are a platform: treat them like one"

2026-10-01 · 10 minute read

Most design systems die the same way: a burst of initial energy produces a component library, teams adopt it unevenly, the library drifts from the product, contributions stall, and three years later there are four button implementations and a Figma file nobody trusts. The failure is rarely craft — the components were fine. The failure is treating the design system as a project with a finish line instead of a platform with customers. Platforms need product management, versioning discipline, support, and adoption metrics. Design systems need all of it, and the teams that run them that way get compounding returns while everyone else rebuilds buttons forever.

## The platform reframe

A component library is an artifact. A design system is a service: it serves product teams building UI, and those teams are its customers. The reframe changes every decision. Artifacts get "finished"; services get roadmaps. Artifacts get documentation; services get SLAs. Artifacts measure output (components shipped); services measure outcomes (adoption rate, time to build a feature, UI defect rate).

**Name the customers and their jobs.** The design system's customers are product engineers shipping features, designers composing interfaces, and — often forgotten — the accessibility and brand stakeholders whose requirements the system encodes. Each has jobs to be done: the engineer wants to build a settings page without designing a toggle from scratch; the designer wants components that match what's shippable; the a11y stakeholder wants every product surface to meet standards without auditing each one. If you can't state these jobs, you're building components for their own sake.

**Staff it like a platform.** A design system run as a 20%-time side project gets 20%-time results. The effective models: a dedicated core team (small — 2 to 5 people — with both engineering and design), or a federated model where a core team owns the infrastructure and product teams contribute components under the core team's review. What doesn't work is no owner at all, or ownership that rotates quarterly. Platforms need continuity; a design system with four owners in two years has no coherent API.

Verdict: if nobody's job description says "design system," you don't have a design system — you have a component folder.

## Versioning and breaking changes: the API contract

Consumers pin a version and upgrade on their schedule — that is the entire value proposition of a versioned dependency, and design systems must honor it. The moment a design system team ships breaking changes casually, product teams learn to fear upgrades, pin ancient versions, and eventually fork. The fork is the death of the system.

**Semver, enforced mechanically.** Breaking visual or API changes are major versions; new components are minor; fixes are patches. Enforce it with tooling where possible: visual regression tests that fail the build on unintended changes, API surface snapshots for component props, codemods shipped alongside majors. The discipline that matters most is the deprecation path: deprecated props/components warn in development, are documented with migration guides, and are removed only after a stated timeline (two majors, or six months, whichever the policy says — written down, not improvised).

**Ship codemods with breaking changes.** The upgrade cost is what determines whether teams upgrade. A major version with an automated codemod that rewrites 90% of call sites gets adopted in weeks; one with a "migration guide" (a wiki page describing manual edits across 400 files) gets adopted never. Codemod investment is platform investment with the highest ROI in the design system's budget.

**Support a version window, not just latest.** Product teams can't all upgrade in lockstep. Supporting the current and previous major — with security and critical fixes backported — is what makes the system safe to depend on. This costs the core team real effort, which is exactly why it needs to be an explicit, funded commitment rather than an aspiration.

## The contribution model: scaling beyond the core team

A core team of three cannot build every component a whole product organization needs. The system scales only if product teams can contribute — and contributions only work with a contribution model that protects quality without strangling throughput.

**The bar for acceptance must be explicit and checkable.** Accessibility requirements (keyboard navigation, ARIA roles, focus management, color contrast), API design conventions (prop naming, composition patterns), documentation (usage guidance, do/don't examples), and test coverage (unit, visual regression). Publish the checklist; automate what can be automated (a11y linting, visual snapshots, API surface checks); review the rest. Contributors should know before they start whether their component will pass.

**Two-tier contribution: incubate, then promote.** Let teams ship experimental components in a clearly-marked incubator namespace (`@system/labs`) with relaxed guarantees, and promote to stable only after real usage, a11y audit, and core-team review. This gives product teams speed without committing the system to every experiment's API. Components that never earn promotion get removed — the incubator needs garbage collection, or it becomes a second, worse component library.

**Recognize that contribution is a tax on product teams.** Contributing upstream takes longer than building locally. The organization has to make it worth it: credit the contributing team, have the core team help with the a11y and docs polish, and — most importantly — make sure leadership treats contribution as real work in planning, not a favor squeezed between feature deadlines. Unfunded contribution models produce exactly zero contributions.

## Tokens: the actual foundation

Design tokens — colors, spacing, typography, radii, shadows as named, platform-agnostic values — are the layer that makes the system more than a React library. Tokens let the same design language reach web, mobile, email, and marketing sites; they make theming (dark mode, white-labeling, brand refreshes) a data change instead of a rewrite.

**Tokens are an API with consumers across platforms.** Version them, document them, deprecate them with the same discipline as components. A token rename without a migration path breaks every platform simultaneously. The token pipeline — source of truth (usually a JSON/YAML spec or a Figma-linked tool), transforms per platform (CSS variables, platform-native formats), and distribution — is build infrastructure that needs ownership and testing like any other.

**Semantic naming over literal naming.** `color-background-primary` survives a rebrand; `color-blue-500` doesn't — or worse, it survives as a lie (`color-blue-500: #e5484d`). Name tokens by purpose, not by value. This is a small decision with decade-long consequences, because tokens are the hardest layer to rename once adopted.

```yaml
# tokens (conceptual): purpose-named, platform-agnostic source of truth
color:
  background:
    primary:   { value: "{color.neutral.0}",  description: "Default page background" }
    secondary: { value: "{color.neutral.50}", description: "Cards, raised surfaces" }
  text:
    primary:   { value: "{color.neutral.900}", description: "Body copy" }
    muted:     { value: "{color.neutral.500}", description: "Secondary / helper text" }
  action:
    primary:
      default: { value: "{color.brand.600}", description: "Primary buttons, links" }
      hover:   { value: "{color.brand.700}" }
      active:  { value: "{color.brand.800}" }
# brand.600 can change in a rebrand; nothing downstream renames

```

## Adoption: the metric that matters

A design system with 60 components and 30% adoption is worse than one with 20 components and 90% adoption. Adoption is the outcome; everything else is output.

**Measure it honestly.** Percentage of product surfaces rendering system components (measured by scanning, not by survey), version currency (how many teams are on supported versions), time-to-first-UI for a new feature team, and UI defect escape rate. Track the holdouts by name — which teams, which surfaces, and why. "Why" is the useful data: legitimate gaps (the system lacks what they need) become roadmap; illegitimate ones (preference, NIH) become management conversations.

**Make adoption the path of least resistance.** The system wins when using it is easier than not using it: scaffolding CLIs that generate system-based pages, starter templates, copy-paste examples for every component, and defaults that are correct (accessible, themed, responsive) without configuration. Every hour a team spends fighting the system is an hour they'll spend justifying a fork. Developer experience is not polish here — it is the adoption strategy.

**Handle the legacy product honestly.** Existing surfaces built before the system won't migrate overnight. The options: migrate opportunistically (touch a surface, adopt the system), run a dedicated migration program for high-traffic surfaces, or formally grandfather low-traffic ones. What doesn't work is pretending they'll migrate "eventually" while the system and the legacy UI diverge for years. Name the grandfathered surfaces and accept the inconsistency as a decision, not drift.

## Governance without bureaucracy

**A lightweight RFC process for significant changes.** New components, token changes, breaking API revisions — anything that affects all consumers — goes through a short written proposal with a decision record. Not a committee meeting; a document with a comment period and a named decider. The goal is shared context, not permission-seeking. (Architecture decision records work well here.)

**Design and engineering co-ownership is structural, not cultural.** If the system lives only in engineering, designers route around it; if only in design, engineers can't consume it. The core team needs both disciplines with real authority, and the Figma library and the code library must be generated or verified against each other — drift between "the design" and "the component" is the fastest way to destroy trust. Ideally the code is the source of truth and design tooling consumes it, not the reverse.

**Deprecation is a governance act.** Removing a component requires knowing every consumer, giving them a migration path and a timeline, and tracking completion. This is platform release management, and it needs tooling: usage scanning across repos, automated PRs where codemods apply, and a dashboard showing migration progress. Teams that "just delete it and see who complains" train consumers to never trust the system again.

## Documentation as the product surface

For a platform, documentation is the UI. Engineers decide whether to adopt a component in the thirty seconds they spend on its docs page.

**Every component needs:** what it's for (and what it's not for), live interactive examples, props API reference generated from types (never hand-maintained — it will lie within a month), do/don't guidance with visual examples, accessibility notes (keyboard behavior, screen-reader expectations), and version history. The props table generated from TypeScript types is non-negotiable; hand-written prop docs are where systems go to mislead.

**Document the system, not just the components.** The getting-started path for a new team, theming guide, contribution guide, versioning and deprecation policy, support channels and response expectations. A component library with great component pages and no "how do I adopt this" guide is a product with no onboarding.

## Anti-patterns

**The big-bang system.** Spending a year building 80 components before any product team uses them. By launch, the components solve last year's problems and the API reflects guesses, not usage. Ship the 10 components every surface needs, get them adopted, and let real usage drive the roadmap.

**Pixel-perfect enforcement over composition.** Components so rigid they can't accommodate real product needs force teams to fork. Prefer composable primitives (headless behavior hooks plus styled defaults) over all-knowing mega-components. The system should make the right thing easy and the custom thing possible — not mandate one true layout.

**No support channel.** "File a Jira ticket" into a void. Platforms need visible, responsive support: a chat channel with core-team presence, office hours during rollout waves, and published response-time expectations. Adoption dies in unanswered questions.

**Measuring components shipped.** Vanity metric. A team incentivized on component count builds components nobody uses. Incentivize adoption, upgrade currency, and defect reduction.

**The rebrand that skips the system.** Marketing launches a new brand and product teams implement it ad hoc because the token pipeline can't deliver it in time. The system must be the fastest path to a rebrand, not the slowest — otherwise the business learns the system is optional.

## Closing

A design system succeeds when it's run as an internal platform: named customers, a staffed core team, semver with codemods, a contribution model with real standards, token infrastructure, adoption measured and driven, and documentation that sells itself. The components are the easy part — any senior frontend engineer can build a good button. The platform discipline is what turns good components into a system teams actually use, upgrade, and contribute to. Treat it like a product, fund it like infrastructure, and measure the outcome that matters: the percentage of your product that speaks one design language.

## Continue reading

- ["Micro-frontends: the narrow conditions where they pay off"](/notes/micro-frontends-the-narrow-conditions-where-they-pay-off) · Note
- ["SSR, ISR, and edge rendering: choosing without the hype"](/notes/ssr-isr-and-edge-rendering-choosing-without-the-hype) · Note
- ["Web performance budgets: make speed a release gate"](/notes/web-performance-budgets-make-speed-a-release-gate) · Note

**Dhruv Doshi** · Toronto, Canada · [work@doshidhruv.com](mailto:work@doshidhruv.com)

[Resume](/resume)[Notes](/notes)[Guides](/guides)[Topics](/topics)[Search](/search)[Research](/research)[Investing](/investing)[LinkedIn](https://www.linkedin.com/in/dhruvdoshi25071999)[GitHub](https://github.com/DhruvDoshi)

[Sitemap](/sitemap.xml)[RSS](/feed.xml)[LLMs](/llms.txt)

© 2026 Dhruv Doshi
