subhrajit.space

a MUI based design system that serves multiple brands

duration
Ongoing
role
UX designer
overview
an experience designer
building data-rich digital interfaces for the last 5 years
now working in design system and AI & agentic interfaces

Context

My current company is a house of brands: five subsidiaries, each acquired over last few years, each arriving with its own design team, workflow, and component library.

The result was fragmentation: localised libraries, different versions of the same core components, inconsistent accessibility, and teams solving the same problems in parallel. Delivery slowed as the portfolio grew.

NXP (the Norstella Experience Platform) was built to be one system every brand could build on. The challenge: standardise without flattening five distinct identities. Too rigid, and BUs would fork it. Too flexible, and we'd rebuild the fragmentation inside one library.

Colour Token Architecture

Colour tokens are built in three tiers, so one set of components can render any brand in either mode.

Primitives hold each brand's raw palette: brand, greyscale, status, and data visualisation scales. Brand is a mode here.

Semantic tokens give colours meaning (text, surface, border) and alias primitives differently per mode. Light/dark is a mode here.

Component tokens assign semantic tokens to specific component parts and states.

Two independent switches, brand and mode, mean a new brand only needs a palette. Every component follows automatically.

Component Library Breakdown

Structure. NXP's 51 components live in four Figma libraries, loosely following atomic design: foundations (colour, type, spacing, elevation, icons, logos per brand) → components → composites → templates.

Specs as contracts. Every component ships with a spec that defines its contract: anatomy, variant and state matrix, token usage, props mapped to MUI's API, a11y notes for both modes, and a changelog. BU designers use it to build; engineers use it to implement.

AI-ready. Each spec also carries a structured YAML block, so the same contract is readable by LLMs and tooling, not just people.

The Hard Decisions

One mapping, different results. The same token mapping passed WCAG AA for Brand A but failed for Brand B (3.8:1 vs the required 4.5:1). We remapped the button background to brand/primary/600 [for all brands / for Brand B only], trading [slight visual change for Brand A / a small per-brand exception] for guaranteed contrast.

Accessibility over rhythm. Truncating list titles to two lines looked cleaner, but hid content from users who zoom or rely on full labels. We chose uneven row heights. Accessibility became non-negotiable in every component contract.

Fixing it at the source. Patching tokens wasn't sustainable. For two BUs, we worked with brand leads to rebuild their palettes as contrast-safe scales, so every step above 600 passes AA on light surfaces. Harder to negotiate, but it fixed the problem for every component at once.

The MUI Bridge

Why MUI. Our products are data-heavy tools where keyboard navigation, ARIA patterns, and edge cases matter more than bundle size. We weighed building from scratch [or headless] against adopting MUI, and chose MUI: it gave us a strong accessibility baseline and components like [Data Grid] out of the box, so we could spend our effort on brand flexibility.

How the bridge works. Semantic tokens map directly onto MUI's palette (main, light, dark), component tokens feed styleOverrides, and each brand × mode compiles into its own theme. Switching brands is a ThemeProvider swap.

We built custom only where MUI had no equivalent, like the vertical filter catalogue.

Implementation in Figma vs Storybook

Early on, we asked: should Figma component properties mirror the code API one-to-one? Using the Accordion as a test case, we compared both models and concluded they shouldn't.

Figma properties are a rendering matrix, not an API. Properties like trailingButtons or iconStart exist so designers can toggle options on a canvas. Turned into code props, they create a rigid, combinatorial surface. In code, a single summary slot handles all of them.

States belong to CSS, not props. Figma needs Hover, Focused, and Pressed as explicit variants because it can't compute them. In code, they come from MUI and the browser. Exposing them as props would add dead weight and drift.

So we reconciled rather than converged. Code is the contract; Figma is the spec. We aligned naming (sizes, icon model), documented adornments as "composed via slot," marked interaction states as CSS-driven, and linked both sides with Code Connect.

The result: a few hours of alignment per component instead of weeks rebuilding either side.

Governance & Adoption

Lean by default. MUI offers dozens of props per component; we expose only what BUs need. New props are added on request, documented in Storybook, and kept backward compatible.

Core, extended, or local. Components enter core when two or more BUs need them. Where a BU needs custom behaviour, slots let them extend a component without forking it. Truly unique needs stay BU-local, and can be promoted later.

Versioning. We follow semver: patches for fixes, minor releases for new props, major releases for breaking API or behaviour changes, always with a deprecation period and migration guide.

Adoption. New products build on NXP from day one. Legacy products migrate screen by screen, prioritised by [traffic / release cycle], so teams never pause delivery for a rewrite.

Impact

New brand in under a week. Setup took 3–4 months. Now launching a new brand means supplying a palette; every component follows.

Faster handoff. Specs and MUI-aligned contracts cut handoff from 3-4 days to an hour.

Fewer bugs. Moving 3 BUs from custom libraries to tested, MUI-based components reduced component bug reports by 80%.

Accessible by default. Core components meet WCAG AA in both modes, and a testing guideline covers custom work.

Adoption. All five BUs now build on NXP. New products start on it by default, and legacy products are migrating incrementally, with over 70% of screens already moved to NXP components.

Reflections

Accessibility first, aesthetics second. A beautiful component that some users can't use isn't finished. Every trade-off in NXP started from that belief.

Contrast-safe palettes should have been a day-one requirement. We patched contrast token by token before fixing it at the source. Building accessible scales first would have saved months of rework.

Adoption needs as much design as components do. Mandating NXP across BUs set the direction, but reducing custom components took more than a rule: it took clear specs, fast support, and components good enough that teams chose them.

What’s Next

Machine-readable specs. Extending the YAML contracts so LLMs can map specs to Storybook stories and generate draft-ready prototypes.

User-controlled accessibility. A high-contrast theme and density settings (compact, default, comfortable), both built as modes on the existing token architecture.

One AI language across five brands. Chat, embedded AI, and agent interfaces share a distinct gradient and motion language that stays consistent regardless of brand, so AI is recognisable anywhere in the portfolio.