UX Case study

A design system is only living if it is used as code

This is a recurring project, one attempt at each company I have worked for since 2017. One difference decided which of them was still in use after I left: whether the library was compiled into the product or filed as a document to be consulted. The method barely changed across all of them, until agentic AI arrived and shifted it slightly. What follows is how the last of them was built, and what the earlier ones taught me by stopping short.

6
Companies, one method, 2017 to today
9
Rules a component had to pass before publishing
6
People on the last team, four of them developers
Clients
Role UX Designer, and the system's product owner by default
Team 4 front end developers, one from each product team, and 2 designers, on a kanban board with no product owner
Timeline Coolblue 2017, Floorplanner 2018, Maersk 2019, Findhotel 2020, and since then Zimmer Biomet 2021 and TrackBee
Platform Component libraries behind web products, on desktop and mobile
Tools Sketch, Figma, Zeplin, InVision, Abstract, Storybook, Chromatic
A page of the style guide showing single line text fields in every state, primary and secondary buttons, sliders and an icon row
Sample of Floorplanner's design system. A text field can have multiple variants depending on its state.

Problem

Nobody decides to build four different buttons

Design in a company of any size is decentralised, for good reasons: a designer sits with a team, learns that team's problem, and ships according to that team's roadmap. The cost arrives later and somewhere else. Put two of those teams' screens side by side and the differences are immediate.

This runs at every scale. At the small end it is a font style that is one step off, or a shade of grey that exists because somebody sampled it from a screenshot. At the large end it is a whole flow that did not need to exist, built because the team that needed it had no way of knowing another team had already solved it.

What makes this hard to fix is that it is not a quality problem. Every one of those screens was made carefully by somebody competent. The inconsistency is a side effect of the structure, so the fix has to be structural too, and a document telling designers to be consistent is not a structure. It is a request.

So the thing to build is not a style guide. It is a place where designers and the front end developers who are inclined to care about user experience can codify a language together, and a route by which what they agree becomes part of the product architecture.

Goals

What a system has to do to be worth the sprint

Consistency the customer feels
The person who benefits never opens the library. They benefit by not having to relearn what a button looks like between one page and the next, which is a cost that is invisible when it is paid and invisible when it stops being paid.
Open enough to be edited
Not a designer's document. Developers, copywriters and product owners all have a claim on how a component behaves, and a system only they are allowed to read is one they will route around the first time it is inconvenient.
Compiled, not consulted
Change the style guide and the products change. If the guide has to be read by a person and then typed again by another person, the two will drift apart, and the drift is the exact problem the guide was built to end.

Team & audience

One sprint in four, and no product owner

The arrangement that has worked best for me is a borrowed team rather than a standing one. One designer and one front end developer from each product team, meeting on a fixed schedule.

Three sprints of ordinary product delivery is how the team finds out what the library is actually missing, so the fourth arrives with a queue somebody has already felt the need for rather than a list of improvements imagined in a room.

It was six people: four front end developers from each team, and two designers. We ran a kanban board and we had no product owner.

Without one, the ticket writing fell to me. Most of it was small and specific. Occasionally it was not: bringing every colour and type token up to W3C contrast guidance for example.

Audience

Who actually opens it

The beneficiary is the customer. The users are four groups in a company.

Front end developers
The group that decides whether any of it is real. They need a component they can import, not a specification they have to interpret.
Designers
They need to be able to take a component off the shelf and trust it, including trusting that somebody else can edit their work without it falling apart.
Copywriters
The most consistently forgotten. Word length, tone and sentence shape are component properties, and a component made only in English at a comfortable length is a component that is likely to break.
Product owners
They need to see what already exists before they scope something that does not need building, which is the cheapest saving in the whole exercise.

Scope and constraints

What did not need an experiment

Almost none of this work was tested, and that was the correct call. Two key decisions made up nearly all of it, and neither is the kind of question an experiment can answer.

The first is removing a variation nobody chose. If a product has three greys where two teams each invented one and nobody can say what the third is for, collapsing them is not a hypothesis. There is no version of the result that argues for keeping an accident.

The second is applying guidance that already exists and is better evidenced than anything we could run ourselves. Contrast ratios are the clearest case: W3C has done the work, at a sample size no single company reaches, and rerunning it locally to see whether our users also prefer being able to read things would be theatre.

When a change genuinely was a question, it left this team. It went down to the product team that owned that flow, where there was a product owner to prioritise it and a data scientist to design the test.

Process

Six steps, and the first three are politics

The order matters. Three of these six happen before a single component is made, and skipping them is how a design system becomes a folder somebody made once.

01

Mapping what is already there

An inventory before a proposal. Colours, text fields, font families, toggles, sliders, popups, buttons, split buttons, galleries, and every variation of each that the product turned out to contain.

The deliverable is the visual version of the list, because a count of thirteen button styles is a number somebody can dispute and thirteen buttons laid out across three slides is not. This is the artefact that makes the next step possible, and it is worth the time it takes.

The catalogue turned out to be its own best exhibit, which I only found rebuilding this page from it. In the case of Findhotel, the primary button is in there three times in three different blues: #3979F5 on the buttons slide, #0074F8 in the header, #4476FB in the dialogues. Nobody intentionally picked three.

Form

13
First name *
Empty input with placeholder
Taipei City
Text input completed with clear option
Empty text input with button
e.g. city, region or hotel
Taipei CityTaiwanDec 15 - Dec 16, 2 GuestsCity
Taipei CityTaiwanNov 24 - Nov 25, 2 GuestsCity
Autocomplete text input
Taipei City
Taipei CityTaiwanDec 15 - Dec 16, 2 GuestsCity
Taipei CityTaiwanNov 24 - Nov 25, 4 GuestsCity
Autocomplete filled input
Choose a bed type1 double bed2 single beds1 double bed and 1 sofa bed2 double beds1 king bed1 twin bed
Select field
Tue, Jan 21January 2020 ›MoTuWeThFrSaSu1314151617181920212223242526
Date field
Telephone number *This does not look like a valid phone number
Error message on an empty input
Requests (optional)
Textarea
Hotel
Checkbox
Expiration MM/YY *12/19
Input with mask
Telephone country code *Netherlands +31
Complete input with validation
Telephone number *0654331553You may be reached at: +31 654331553
Empty input with info

Buttons

13
Search
Primary button
Filter by
Secondary button
Reset
Quiet button
Go back to search
Link button
Unlock Deal
Private deal button
Field icon button
Show details
Accordion button
EN€
Button row
English
List icon text button
Delft
Anchor button
Icon button
9+
Toggle button
Best match
Radio button

Display

9
The price for this hotel has dropped today
Tooltip
Private deal unlocked8.3Efficient check-in/check-out
Chips
Stars
Couples50%
Progress bar
Spinner
Searching all the best travel sites
Toaster
We use cookies. Continue browsing if you are okay with that.
Overlay banner
Unfortunately the price has changed.The price raised from €181.72 to €182.00Secure bookingIt takes only 2 minutesThe deal you chose is no longer availableWe found you these other great deals
Inline banner
Property TypeHotel854Apartment212Guest house63Hostel29Bed and breakfast11Inn4Show more
Filter options

Containers

8
Movenpick Hotel AmsterdamOostelijk Havengebied8.8FabulousBooking.com€111View DealACCOR€111€105View Deal
Card
Check in/Check outCheck in from 15:00Check out prior to 12:00GeneralPaymentHouse rules
Expansion panel
Booking.com€141View Deal
Clickable row with hover
Option 1Free cancellation↑ Before Mon, Jan 20€123Reserve
Row
Booking.com€92View DealExpedia€94View DealHotels.com€94View Deal
Row list
Divider
FINDHOTELEN€
Header section
Footer section

Images

Avatar
Image thumbnail
Image, one round corner
Image with round corners
1/49
Image

Menus

FINDHOTELEN€EnglishEspañolFrançaisPortuguêsItalianoDeutschNederlandsPolskiTürkçeSvenskaDanskNorskSuomiČeštinaMagyarRomânăHrvatskiSlovenščinaEestiLatviešuLietuviųFilipinoMelayuSlovak
Dropdown menu
PreferencesEnglish (en)Euro (€)About UsPrivacy PolicyHotels FAQContact
Burger menu
AmsterdamCheck InTue, Jan 212 Guests, 1 RoomCloseSearch
Expansion menu

Navigation

View on Google Maps
Link
Link list
PhotosDetailsLocationReviewsDeals
Tabs

Overlays

FINDHOTELEN€Sold out on your datesLooks like there are no longer any rooms available for the dates you selected.Back to previous page
Page overlay
Payment failedSorry, we could not process your payment. Please try again.Back to formCustomer Support
Dialog
  • #3979F5Buttons slide, Search
  • #0074F8Header section, Search
  • #4476FBDialog, Back to form

One primary button, three blues. This is the inventory arguing its own case.

02

Buying the time

With the inventory in hand, a lead developer and I put a presentation in front of the people who sign off on where sprints go. The audience picked itself. The people who had been complaining that the product does not look like itself in different places were the ones who would make this real, because they had already noticed the problem and had no name for it.

That is the whole trick of this step. Nobody funds a design system as an abstraction. They fund it once they have seen the thirteen buttons, at which point the argument is no longer that consistency is good in principle.

The deck asks what the problems are and answers with the plain answers: features ship slowly, nobody is sure which components already exist or how to use them, small bugs in components never get fixed, accessibility is missing across the application. Read on its own it is the case that could be made at any company.

03

Composing the team from every team

One designer and one developer out of each product team.

A team drawn from everywhere has a representative in every room where the library will later be used. That is what turns adoption from a rollout into something that has already happened, and it is the difference between a library the company uses and a library its authors use.

Four product teams, and the six people who put their strengths together: four front-end developers and two UX designers.

04

Choosing tools

On the design side this came down to two decisions: what to draw in, and where to publish. At Maersk in 2019, InVision was already licensed and widely used. At Findhotel it was Zeplin. Both companies used Sketch. In each case the answer was the tool already in use.

On the development side there was a new requirement rather than an inherited one: the main consideration was to make the process of publishing and debugging a component as automatic as possible.

Times have changed since then; Figma is widely used as the preferred tool for UX designers. Storybook still holds its place in the development cycle. What actually moved sits underneath the tools. A designer working with agentic AI like Claude Code can write and commit the component directly, instead of relying on a developer to implement changes.

2019 2020
Figma The online alternative, and still very much the challenger, not yet the default.
Storybook The other end of the same shelf. A component that exists here exists in the product.
Zeplin The source of truth both sides looked at. Everything below is arranged around keeping this one honest. Fallen out of use
Sketch Where the components were drawn, and the seat both companies had already paid for. Fallen out of use
Chromatic What made a pull request something a designer could review, by turning a diff into a picture. Fallen out of use
2026
Figma Stayed exactly where it was, except it is no longer the challenger. It is simply the platform people design in.
Storybook Still the other end of the same shelf, for the same reason it always was.
Claude Code The actual change. A designer can write and commit a component here directly, so the handoff above is sometimes just one person, one file.
05

Making components, and agreeing what one is

Divided among the designers, one component at a time, and the unit of work is the component in all of its states.

Two designers dividing that work will produce two incompatible halves unless somebody writes down what finished means, so I did. Nine conditions were written as a form of an acceptance criteria for the design system.

  1. Flexible to resizing with autolayout
  2. Using the official list of named font styles
  3. Using the official list of named colours
  4. Fitting exactly within the unit grid which has 4px as its smallest unit
  5. Carrying a mobile, tablet, and a desktop version, where that applies
  6. Exposing the fewest editing permissions that still make it useful
  7. Properly named, including every sublayer
  8. Tested on a canvas for resizing and for permissions
  9. Published to the official platform

Three of them are worth seeing rather than reading, because each is a rule about a shape.

Shape rules

PlaceholderPlaceholder1u = 8px
Placeholder
2u
2u
Placeholder3u
2u
Placeholder
Placeholder
1.5u1u1u
One unit is 8px, and every edge of the component lands on a whole number of them.
PlaceholderUser inputUser inputUser inputUser input
Six states, not one: normal, focused, filled, disabled, error, and resolved. All states of one component.
Placeholder
Placeholder
Placeholder
Which parts stretch and which parts hold, decided once rather than per artboard.
06

Publishing, which is where the argument is settled

This is the step my earlier attempts got wrong, and getting it wrong does not look like failure at the time. With InVision I published to designers. Designers used it. The results were fine and the products drifted anyway, because a design silo and a development silo produce the same drift as no system at all, one handover later.

Design becomes code eventually or it does not ship. So my work went straight at the developers. Components were mapped one by one between the design side and the development side, each with a unique URL indexed in a file the front end could read.

Below is one component, the star rating, in all the three places it exists. It is the same object with variations.

What shipped

Pages that came out of the design system

These pages are assembled entirely out of parts made in their corresponding design systems.

Floorplanner, 2018

A drawing tool rather than a funnel. The two marketing pages at the end are the interesting ones, because a marketing page assembled from the product's own components is an example case where the guide reached beyond the core product.

Maersk, 2019

Twill, Maersk's platform for the small and medium exporters and importers who book LCL (less than container load) cargo: shipments too small to fill a container, sharing the space and the cost with other people's freight. The screens below follow one booking from the destination search to the confirmation screen.

Findhotel, 2020

The whole funnel, on desktop, tablet, and mobile. The mobile captures are full page exports.

Zimmer Biomet, 2021

A surgical planner, built over eighteen months. Most of the dialogues in this product are one component with different content inside it. Change the component once and every dialogue changes with it.

TrackBee, 2025

Five flows shown at three widths each: signing in, creating an account, connecting ad platforms, choosing a plan, and coming back after a lapsed subscription.

Conclusion

A living design system is a system that is coded

Used in every product

By the time I left it was a live library, imported by every product in the portfolio rather than referred to by them.

Every component becoming accessible

Bringing every component up to W3C accessibility guidance changed every product at once, which is a clear example of success.

At Coolblue in 2017 and at Maersk in 2019 what I built was aimed at designers, with limited developer involvement, and both were left at the mercy of whoever was sitting in a given team: it was that designer's job to reach for the components, to keep them current, and to apply them properly. That is too much to hang on one person's diligence, and it is not a criticism of any of the designers involved. A system whose enforcement mechanism is somebody remembering is a system that degrades on the first busy sprint.

Lessons

A silo on either side does the same damage
Even if the design side agrees perfectly and hands over the material to a development side, the developers who implement the system from a picture or a guide will produce exactly the same drift in the intended design, just one step later.
One source of truth, no more drift
The principle that has done the most work for me, and the one that is easiest to break by accident. Every other place a component is described is a place where there will be drift.
Make improving cheaper than starting over
Designers and developers will keep producing. Software development just does not stop. Working on the existing components is the path of least resistance. The goal is to improve the project's future instead of starting over.