Building a Multi-Framework Design System at Enterprise Scale

STRATEGY

UX DESIGN

Enterprise Design System

Overview

Magnit was acquired by EQT in 2021 and then bought five companies in two years. Each one arrived with its own interface conventions, its own component patterns, and its own idea of what a button looked like. At the same time we were rebranding from PRO Unlimited to Magnit, which meant every surface was going to be touched anyway.

We had two front-end stacks and no shared vocabulary between them. Teams were rebuilding the same components independently, accessibility was inconsistent by team rather than by standard, and every acquisition made it worse.

I led the effort to build a design system that could serve both stacks from one design language, and to make it the path of least resistance rather than a set of rules someone had to enforce.

Role

Senior Director of Design

Team of 3 designers & 3 front-end developers remotely

The Problem

The obvious version of this problem is inconsistency. Different teams shipping different buttons.

The real version is more expensive. Without a shared component layer:

  • Every team solves accessibility independently, which means most of them solve it badly or not at all

  • The same component gets built three times, and the three versions diverge immediately

  • Design-to-development handoff becomes a translation exercise, because there is no shared vocabulary to hand off to

  • Onboarding a new engineer means learning one team's conventions rather than one company's

  • Every acquisition compounds all of the above

And we had a complication most design systems don't: two frameworks. React and Angular, both in production, neither going away.

The core question wasn't "what should our components look like." It was "what has to be true so that doing the right thing is also the easy thing."

Abstract image used as a placeholder for this design project
Design specs
Tokens

The Approach

Most design systems fail the same way. They ship a component library, adoption stalls at 40%, and the system becomes a suggestion.

We treated it as an architecture problem rather than a library problem. If the primitives are right, consistency is a property of the system rather than a thing you have to police.

Key Decisions

1. One foundational primitive, everything composes from it

Box is the base component in the system. Every other component is built on top of it, and it's polymorphic, meaning it can render as any element while keeping its styling contract and type safety.

Why it mattered

  • Consistency became structural instead of enforced. You get the spacing scale and the type system whether you want them or not

  • New components are cheap to build because the foundation already handles layout, spacing, and element polymorphism

  • The type system catches misuse at compile time rather than in review

  • Trade-off: a steeper initial learning curve for engineers used to writing components from scratch. Worth it, but real

2. Build on Radix primitives rather than from scratch

Checkbox, Dialog, Popover, and the other interaction-heavy components sit on Radix UI primitives instead of custom implementations.

Why it mattered

  • Keyboard navigation, focus management, and ARIA semantics come correct by default rather than being reimplemented and subtly broken each time

  • Our team's effort went into the design language and the enterprise-specific components, not into rebuilding a dialog that already exists

  • Accessibility conformance became a property of the foundation, which is what made the WCAG program achievable at all

  • Trade-off: a dependency on someone else's release cadence

3. Zero-runtime stylesheets, precompiled with TypeScript

Styles are compiled at build time rather than resolved in the browser, with the type system covering the styling API.

Why it mattered

  • No runtime style computation cost on data-heavy enterprise screens, which is where our users actually live

  • Design tokens became type-checked. A typo in a color name fails the build instead of shipping

  • Theming, including light, dark, and high contrast modes, resolves at build time rather than being layered on

  • Trade-off: less runtime flexibility, which for an enterprise product suite is the right side of the trade

4. Two frameworks, one design language

React and Angular implementations share design tokens, naming, and behavioral contracts. The implementations differ. The language doesn't.

Why it mattered

  • A designer specifies once, and both stacks understand it

  • Teams could migrate between stacks without relearning the vocabulary

  • It made the system framework-agnostic in the way that actually matters, at the token and contract layer, rather than pretending one framework could serve both

  • This is the hardest part of the work and the part most design systems never attempt

5. Accessibility as structure, not a checklist

ARIA support, focus behavior, and semantic markup live inside the components. Theme-aware light, dark, and high contrast modes are built into the system rather than applied over it.

Why it mattered

  • Every new page built on the system ships at WCAG 2.1 AA by default, which is what let us change the accessibility problem from remediation to prevention

  • Teams stopped needing to know accessibility rules to comply with them

  • It's the reason the accessibility program had something to stand on. The system and the program are the same work at two altitudes

6. Public, versioned documentation

The system is documented publicly with a full component reference plus separate Types, Hooks, and Utils API surfaces.

Why it mattered

  • Documentation as a product, not an afterthought. If it isn't findable it isn't adopted

  • Exposing Hooks and Utils meant teams could build system-consistent components we hadn't shipped, instead of going around the system

  • Public hosting made it linkable in RFPs, in onboarding, and to partners

Case study project image 5
Case study project image 6

What Shipped

  • 42 components, from primitives like Box, Flex, and Stack through to a DataGrid built for unlimited data sets

  • Three API surfaces beyond components: Types, Hooks, and Utils

  • Two framework implementations, React and Angular, sharing one token layer

  • Full TypeScript coverage across the styling and component APIs

  • Light, dark, and high contrast theming

  • Public documentation with per-component usage and accessibility guidance

Case study project image 7

Results

  • Adopted by 5+ scrum teams

  • 40% reduction in design-to-development handoff cycles

  • 15% reduction in support ticket volume across re-architected applications

  • New design-system pages ship at WCAG 2.1 AA by default, which converted accessibility from a remediation backlog into a prevention model

Reflection

The lesson I took from this is that design systems don't fail on component quality. They fail on adoption, and adoption is an architecture problem before it's a persuasion problem.

Every decision here was aimed at the same thing: making the correct path also the easiest one. Compose from Box because it's less work than not. Get accessibility for free because it's built into the primitive. Use the tokens because the build fails otherwise.

By the time we ran a formal accessibility program, the system had already made most of the problem structural. That wasn't luck. It was the point.