Building the MetaMask Design Systems
MetaMask’s product teams were shipping fast across web and mobile, but UI patterns and tokens were drifting. I led the build-out of a shared design system foundation—starting from the components teams needed in-flight—so adoption grew without slowing production, improving consistency while keeping teams free to innovate.
Understanding the Pain Points
Fast shipping without a shared design–code contract led to three issues: duplicated work (one-offs and rebuilds), pattern drift that created bugs and QA churn, and no clean contribution path—so new needs stayed as one-offs instead of becoming reusable system patterns.
1. Defining the Contract
Lever one was defining the contract — so patterns are predictable to build and hard to fork. I did that in three moves:
—
Shared design variables — semantic tokens that map cleanly to code.
Component APIs — Figma variants aligned to real props and states, so engineers don’t reinterpret designs.
Flexibility by design — clear customization lanes inside the system, so teams can ship without detaching.
2. Ship adoption like a product
I built adoption intentionally: a clear contribution path to prevent one-offs, migration and upgrade steps so teams could adopt without slowing delivery, and an enablement loop—office hours, fast reviews, and lightweight docs—to keep teams unblocked. I tracked leading signals like Figma usage and detaching trends, surveys, codebase adoption, and office-hour demand to ensure adoption was real, not just published.
3. Measure + Sustain
I sustained the system by running it like a product over time: setting quarterly OKRs and lightweight health metrics (adoption, parity, NPS) to catch drift early, defining clear boundaries between global patterns and domain-owned needs to avoid becoming a bottleneck, and making the “right path” the easiest path through docs, templates, migration guidance, and fast support—so reuse became the default.
The Outcome
The design system reduced delivery effort by ~40% by baking accessibility and UI quality checks into the components, cutting repeated audits and rework each sprint. Beyond efficiency, it improved consistency and design–code parity as adoption spread across teams—giving the product a stable foundation to rebrand quickly and keep evolving without the UI fracturing.














