Enter password to view case study
CASE STUDY
A design system only works if design and engineering are looking at the same thing. When I took this one over, that wasn't the case. Components no longer matched what was actually live in production, screens across different flows looked inconsistent, and nobody on the design team fully trusted the file they were building from.
This is a look at how I rebuilt it: starting with the variables, then the components, then the overall structure, and finally the documentation that tied it all together.
THE PROBLEM
I inherited the system from my predecessor, and it became clear pretty quickly that it hadn't been set up properly in the first place. A few problems kept showing up:
Components in Figma didn't reflect what was actually shipped in code, so designers were working from a UI that no longer existed.
Screens and flows were inconsistent with each other. Because the components couldn't be trusted, people had started detaching instances and building their own one-off versions, so the same "component" could look completely different depending on which file you opened.
There was no real source of truth. Every new project just repeated the same inconsistencies, and it made handoff to engineering harder than it needed to be.
Before I could fix any of the components themselves, I needed the foundations underneath them to actually be correct.


STARTING WITH VARIABLES
Instead of jumping straight into components, I started with the variables. If the tokens for colour, spacing and typography didn't match production, then anything built on top of them would inherit the same problem.
I went through the existing variables and checked them against the live code rather than trusting what was already documented in Figma. Where things didn't match, I rebuilt them so each token had a real, working equivalent on the front end. I also grouped variables into clearer collections, so colour and spacing weren't tangled together and designers could update one without accidentally affecting the other.
This gave the system a base that was actually true, which meant everything I built after this point could be trusted rather than double-checked.

Reworking the Components
Once the foundations were solid, I moved on to the components. A lot of them were rigid: single-purpose, hard-coded, and unable to adapt to real content or different layouts. That rigidity was a big part of why people had been detaching instances and rebuilding things from scratch in the first place.
I reworked components so they had proper properties (variants and swappable instances) to cover different states and use cases without needing duplicates. I built in flexibility using auto-layout and constraints so components could handle real content lengths and different screen sizes instead of breaking. And I added layout guidance so people knew how a component was meant to sit on a page, not just what it looked like on its own.
This also gave us the chance to properly redesign, update and improve components that had been carried over from the old legacy system, rather than just patching them. It meant we could produce clean code alongside a fully functioning Figma component, so both sides were built right from the start instead of one playing catch-up with the other.
The idea was simple: make the right way to use a component also the easiest way, so there was no reason left to detach it and go it alone.


Structuring Around Atoms, Molecules and Organisms
To stop the system turning into a flat, disorganised list of components again, I structured it using atomic design: atoms, molecules and organisms, with nested components carried through each level.
Atoms came first, since everything else depended on them being solid. Buttons, inputs, icons, tags. Molecules combined atoms into small functional pieces, like a form field with a label and helper text, nesting the atom components rather than rebuilding them from scratch each time. Organisms then combined molecules and atoms into larger sections like cards or navigation bars, inheriting everything nested beneath them.
Because the nesting was done properly, a change to a single atom, say a new button state, would automatically flow up through every molecule and organism using it. No manual updates across the file, and no risk of things quietly falling out of sync again.
Documentation That Actually Gets Used
None of this matters if people don't know how to use it. I wrote clear documentation for each component directly in Figma, covering how it should be used and what to avoid, and mirrored the same documentation in Storybook so engineering had a code-level reference that matched the design file exactly.
That meant designers had guidance right at the point of use instead of buried in a separate doc somewhere. Engineers could check Storybook against Figma and see the same component, the same states, the same naming, closing the gap that caused the original mismatch. It also made onboarding new team members quicker, since the reasoning behind each component was documented alongside the component itself.


Outcome
Rebuilding from the ground up, rather than patching individual components, meant the system became something both teams could actually rely on again. Design and production code lined up. Flows and screens looked consistent across files because people no longer needed to detach components to get what they needed. Updates scaled properly thanks to the atomic structure, and the documentation in Figma and Storybook gave both teams a shared reference they could trust.
In total, 52 components came out of this: 21 rebuilt from the legacy system, and 31 new ones that should have existed already but never did.