Summary
A design system is a versioned product consumed by product teams: it packages design tokens, a component library, documentation, and a contribution model. The cost is real — a dedicated team of 2–4 engineers is the industry baseline. The payoff is consistency at scale and faster product iteration once adoption crosses a threshold.
Jump to the interview angleA design system bundles four layers into one versioned package: design tokens (color, spacing, typography as CSS custom properties or JSON), a component library (accessible, token-consuming UI primitives), documentation (live playground, usage guidelines, accessibility notes), and a governance model (who can merge, how to request new components, how breaking changes land).
The package ships as an npm package — e.g. @acme/ui — so consuming teams pin a version and upgrade deliberately. Without semver and a changelog, it is not a design system; it is a shared folder.
What a design system contains
- Design tokens: named CSS custom properties (--color-brand-500) generated from a source-of-truth JSON file.
- Component library: accessible, token-driven primitives published as an npm package with TypeScript types.
- Documentation site: live Storybook or equivalent with prop tables, usage rules, and a11y guidance.
- Versioning: semver — patch for bug fixes, minor for new components, major for breaking API changes.
- Governance: a contribution guide and RFC process so teams can propose without bypassing review.
Shipping a breaking change safely
- 1
Deprecate, don't delete
Add a console.warn or TypeScript @deprecated tag in the current minor. Give consumers at least one release cycle before the breaking change ships.
- 2
Write a codemod
Use jscodeshift or ts-morph to automate the migration. A codemod turns a breaking change from a blocker into a one-command upgrade for most teams.
- 3
Cut the major version
Bump to the next major via semver, publish a MIGRATION.md, and list the codemod command. Pin old major in an LTS branch only if the org has strict upgrade policies.
- 4
Announce and track adoption
Post in #design-system with the migration command. Track the old API usage via a custom ESLint rule or import analysis until adoption reaches zero.
Build vs. adopt an existing system
Pros
- Consistent UI across products without per-team CSS drift.
- Accessibility handled once in the library instead of per component per team.
- Tokens enable a single theming change to propagate everywhere instantly.
- Frees product teams from low-level UI work once adoption is high.
- Shared vocabulary speeds design-to-engineering handoff.
Cons
- Requires 2–4 dedicated engineers; an unmaintained system is worse than none.
- Breaking changes need codemods and deprecation cycles — releasing slows down.
- Product teams must wait for the system to support their use case or fork.
- Adoption is voluntary until mandated; expect a long tail of inconsistent usage.
- Wrong abstractions calcify fast — early API mistakes cost compounding migration work.
The maintenance trap
Teams build a component library, then dissolve the working group. Within six months, product teams fork components and the system fragments. A design system needs a named owner, a public roadmap, and a contribution SLA — or it should not be built. Adopting Radix UI or shadcn/ui with custom tokens is a valid alternative for smaller orgs.
Interview angle
Interviewers probe whether you treat a design system as a product, not a repo dump. Discuss semver, breaking-change codemods, adoption metrics, and when NOT to build one.
Soundbite: "A design system is a product with consumers; ship it like one — semver, changelogs, codemods for breaking changes."
Key terms
- Design tokens
- Named, platform-agnostic values (color, spacing, type) stored as JSON and compiled to CSS custom properties or platform constants.
- Semver
- Semantic versioning: patch.minor.major — major bumps signal breaking API changes that require a migration.
- Codemod
- An automated script (jscodeshift, ts-morph) that rewrites source code to migrate a breaking API change.
- Contribution model
- The RFC and review process defining who can add or change components and under what conditions.
- Adoption rate
- Percentage of product surfaces using the system's components; tracked to justify maintenance cost and deprecate forks.