OM
EN ES

Situation

Enterprise product surfaces shared branding across Angular applications—and a React viability check—while tokens and components risked drifting when each consumer evolved them alone.

Task

Establish a shared design-system foundation: semantic tokens, composition rules, and versioned packages that teams could adopt without locking every product to a single UI runtime.

Action

Kept the core to tokens, composition rules, and primitives; left business widgets outside the library. Generated semantic tokens from a JSON config through a build pipeline, shipped versioned packages with review, changelog, and deprecation discipline, and documented usage via in-library demos plus Storybook.

Result

Angular apps could migrate onto v3 module by module instead of in a big bang; a short React PoC validated cross-framework consumption without forcing full parity.

System shape

In the core: color, type, and space tokens; composition rules for how UI is assembled; primitive components (button, input, card, and similar).

Outside the library: business widgets tied to a specific product domain.

How teams learned it: a demo section inside the library for small form/layout examples, plus Storybook for documentation.

Who consumed it: Angular apps were the production path. React was a short viability PoC—useful signal, not the primary investment.

Decisions

Semantic tokens from a generated source of truth

Chose: semantic tokens defined in a JSON configuration and produced by a build/generation pipeline. Rejected: hand-copying raw token values into each app or framework package. Why: one source of truth keeps naming and values aligned; framework packages consume artifacts instead of forking the palette.

Asymmetric Angular vs React investment

Chose: deep adoption on Angular; React only as a PoC when the client asked whether it would work. Rejected: forcing full Angular/React parity from day one. Why: most real consumers were Angular. A short PoC answered the React question without delaying the system that production apps needed.

Versioned packages, not a mega-bundle

Chose: independently versioned packages (core + component packages). Rejected: a single unversioned mega-package that every app had to swallow whole. Why: consumers can upgrade deliberately; majors can be announced before they break builds.

Governance and versioning

  • Changes were reviewed before merge.
  • Releases were versioned; major bumps were communicated to the client ahead of time so consuming apps could plan.
  • Every release required a changelog and explicit deprecations—no silent breaking shifts.

Adoption path

React PoC (short): a greenfield demo installed core plus component packages (button, inputs, cards, and similar) only to validate feasibility.

Angular (real adoption): the client already had two prior design-system generations. v3 was a full redesign, so migration was module by module on apps shipping new surfaces—not a big-bang rewrite of every screen. The design-system team and app module builders kept a tight feedback loop: early issues turned into fast, durable patches rather than long-lived forks.

What we refused

From the start we refused to:

  • Put business widgets inside the library core
  • Copy tokens by hand into each app
  • Force full Angular/React parity on day one
  • Ship one mega-package without versioning
  • Skip changelog or deprecation notes on releases

Transferable lesson

Before changing an existing design system, learn it through its documentation—and leave the system more documented than you found it. Creating “something new” without that loop only recreates drift.

Limits of this write-up

This narrative is anonymized. No proprietary token files, internal package names, product screenshots, or client brands are shown. Client work under NDA — architecture and decisions shown, product details withheld by design.