The outcome

Over three years at Visibuild, I helped turn a collection of one-off UI decisions into a shared system the product team could design and build with. I led the token architecture, component direction, and adoption work, then moved closer to the codebase to help carry those decisions into production.

By the end of that work, the system included 280+ tokens and 100+ components. Across the categories we audited, bespoke implementations fell by roughly 30 to 50% while the product team grew from 9 to 19 people.

MetricBeforeAfterChange
Bespoke button styles~15079↓ 47%
Bespoke input styles~13080↓ 38%
Bespoke modal implementations~4520↓ 55%
Standardised components0100+New
Design tokens0280New
Token usage (SCSS)02,000+ instancesNew

The problem

When I joined Visibuild, nearly every interface primitive had been solved more than once. Buttons, inputs, modals, spacing, and colour all varied across the product because teams had no shared source of truth.

The cost showed up in repeated implementation work, slower reviews, and constant clarification between design and engineering. As the team prepared to grow, every new feature risked adding another local solution to the pile.

The audit

I began with a systematic inventory using the Design System Guide's audit template. Over a month, alongside other product work, I documented the visible patterns and traced their coded implementations.

  • Built a Notion database cataloguing component variants in production
  • Captured styling inconsistencies in Figma so the team could compare them together
  • Mapped buttons, inputs, modals, typography, colour, and spacing treatments

The visual audit found 23 distinct button patterns. A later code audit counted roughly 150 individual bespoke button implementations, which is the baseline used in the outcome table above.

The same pattern appeared elsewhere. Modal quality varied with no shared model, colour values were hardcoded without a source of truth, and spacing was often decided one screen at a time.

The audit gave us more than a baseline. It made the cost of local decisions visible to the whole team, which meant the need for a shared system no longer depended on one person making the case.

Sanitised screenshot of Notion inventory database showing component cataloguing

Building the foundation: tokens first

We started simple: colours, typography, and spacing.

These foundational tokens were built in Figma using Token Studio, creating a single source of truth that could be exported to JSON, JavaScript, and SCSS. Within two months of starting, we had our first tokens shipping.

Visual diagram showing Base Tokens flowing to Semantic Tokens flowing

The tokens became a shared language. When a designer specified space-8 in Figma, a developer could implement it without another round of interpretation.

Adoption was a design problem too

Some designers worried that a system would constrain good work. Rather than treating that concern as resistance, I used workshops to establish where consistency helped and where product teams still needed room to solve new problems.

The goal was not to remove creative decisions. It was to remove repeated decisions so designers and engineers could spend more attention on the parts of a workflow that were genuinely new.

Tokens only work if people use them, so the shared language had to appear in the development workflow too. We partnered with engineering to implement Stylelint rules that guided token usage:

RulePurpose
no-raw-valueFlags hardcoded colours and spacing
incorrect-tokenCatches misapplied token usage
no-core-tokenEnsures semantic tokens are used over primitives

The rules made feedback immediate and specific. Instead of relying on someone to spot every raw value in review, the tooling showed what needed to change while the code was being written.

Components: collaboration over handoff

By month four, we shipped our first standardised Button component with 11 variants covering every legitimate use case we had identified in the audit.

As the component library grew, review comments were no longer the fastest way to protect design intent. I began working directly in the front-end codebase, first refining shipped components, then implementing states, variants, tokens, and interaction details myself.

Engineering review remained part of the process, but the feedback loop shortened. I could test a system decision in the environment where it had to survive.

  • Individual product streams could propose components that would benefit the system
  • I reviewed each proposal against clear criteria: Is this a snowflake (one-off need) or does it have genuine reusability?
  • Promising components were tested across multiple contexts before acceptance
  • Governance stayed lightweight with conversations, not committees

The result was a system that grew from real product needs rather than theoretical completeness. Product teams began proposing reusable components themselves, which was a stronger adoption signal than simply following documentation.

Scaling the team

The design system became our onboarding accelerator.

As Visibuild grew from 9 to 19 people, each new designer and developer received an introduction suited to their role. Designers learned the token structure in Figma. Developers learned the component library and linting rules.

The system gave new team members a map of the product's primitives before they had learned every part of the codebase. Routine interface decisions had an existing answer, and the contribution model explained how to challenge or extend it.

Simple infographic showing team growth from 3 designers + 6 devs to 4 designers + 2 PMs + 13 devs

The resulting system

By the end of my time at Visibuild, the system included:

CategoryStatus
Design tokens280 across colour, typography, spacing, motion, and elevation
Standardised components100+ with consistent APIs
EnforcementAutomated via Stylelint
Platform supportSCSS, JavaScript, Ruby
Usage2,000+ instances across 345 files

The migration was not complete. The foundation was established, but a meaningful backlog of bespoke styles and deprecated components remained:

TaskCount
Bespoke button styles to migrate79
Bespoke input styles to migrate80
Deprecated components to remove2
Files with migration TODOs134

Looking back

The biggest mistake was delaying enforcement. Every week between publishing the tokens and making them easy to use in code allowed new hardcoded values to accumulate.

The broader lesson has stayed with me: a design system is not the library. It is the set of decisions, tools, and team habits that make the coherent choice easier to ship. The components mattered. The shared language and feedback loops are what made them durable.