HR · Design Systems

Tesco

Designing an internal B2B SaaS performance-management product for 367,000+ employees — and building the design system it needed from zero.

Role Senior UX Designer
Domain HR / People Management
Platform Web
Period 2021–2023

Who it’s for

The conversation every employee has once a year

Tesco is the UK’s largest retailer. Somewhere in it, 367,000 people have a yearly conversation about how their job is going and where it goes next.

The Performance Management Application is where that conversation lives. HR teams and line managers use it to set goals, agree priorities, build development plans and run the annual appraisal — a B2B SaaS product with an internal audience, which is its own kind of hard: your users cannot churn, they can only resent you.

In 2020 Tesco set out to improve how it talks to colleagues about their careers. PMA was the product built to do it.

The PMA objectives screen showing the performance timeline for 2020-2021, one objective card and two review forms
Where the conversation starts: your objectives for the year, and the two reviews that check them.

The wall

The design system we were supposed to build on did not exist yet.

Tesco already had many products, and the core design team was building a company-wide system at exactly the moment PMA development started. It was not available to us. Every variation had to be drawn by hand, and without shared components the experience came out slightly different on every screen.

The choice

Three options, none of them free

We could wait for the central system and lose months. We could invent our own and guarantee a painful divergence later. Or we could build a bridge: a separate sub-library, made to be folded back into the main system once it landed.

We took the third. It bought the delivery team speed immediately, at the cost of a merge we knew was coming and would have to pay for.

We built it in Figma specifically for the real-time collaboration — not for the drawing tools, but because it stopped the team burning hours on which file was current.

What this case is not

This was a design-operations problem, not a research one. The evidence here is delivery data — how much got built and how fast — not user testing. Worth saying plainly rather than dressing it up as something it was not.

1. Tokens first

Type, colour and spacing given one source, applied across the whole design.

2. Components with every state

Default, hover, loading, expanded, filled, disabled — defined once, not redrawn per screen.

3. Applied across every journey

Then the file organised by version, so the team could see what changed and when.

The PMA component library in Figma, with a page list of components, a canvas of table and grid variants, and the text and colour styles panel
The sub-library itself: components down the left, every variant laid out on the canvas, and the type and colour styles they all draw from. Deliberately boring — boring is what survives a merge.

Inside the library

Rules, not just shapes

A component is only reusable if the decisions around it are written down. Each one came with three things: its anatomy, its full set of states, and the words that go inside it.

That is what stops a library drifting. A designer joining the file does not have to guess which grey means disabled, and a developer does not have to ask what the error message should say.

The copy was part of the job, not someone else’s. Empty states especially — I wrote the title and description for every one, page by page. “No data” is a dead end; the empty state is the one moment where you can tell someone what to do next.

A greyscale anatomy diagram of the top navigation, showing the three-level full version for managers and the two-level limited version for general colleagues
The navigation drawn in greyscale first, so the structure gets argued before the styling does.
A table of empty-state copy listing page, state type, title and description for calibration sessions, actions, objectives and tips
Empty-state copy written out page by page, state by state.
The radio button specification page: a matrix of ten states, length and spacing options on white and grey backgrounds, error messages and tooltips
One component, fully specified: ten states, spacing on both backgrounds, error messages, tooltips.

How it paid off

One change, everywhere at once

The point of a library is not tidiness. It is that when a designer updates a component, every page in the file updates with it — so a decision taken once stops needing to be re-taken on thirty screens.

It also constrains usefully. A component library keeps designers inside the product’s own rules, which means fewer surprises reaching development and fewer arguments about whether something is a variant or a mistake.

An objective open in a side panel, showing its steps, pending approval status and a history of edits
The same side panel, now reviewing an objective instead of creating one — status, steps, edit history, all assembled from the same parts.
The objectives screen with no objectives yet, prompting the colleague to add their first one The objectives screen with four objectives, progress rings, a carousel and a pending-approval tooltip
The same screen with nothing on it and with a year’s work on it. Empty states are where hand-drawn designs usually drift; here both came out of the same components.
The Add new objective panel in its empty state, with placeholder text and disabled buttons The Add new objective panel filled in, with a step being typed and the submit buttons enabled
And one panel across its states: empty with disabled actions, then filled with a step mid-entry. Defined once in the library, not redrawn per screen.

What changed

Half the time, and a system that outlived the project

We designed and shipped 35+ flows against the library, and completed the project in roughly half the time it would otherwise have taken. Handoff to development got noticeably quieter — fewer rounds of “is this intentional?”

Tesco launched the first release and kept improving it in later ones, adapting the tool for different colleague groups. The sub-library folded back into the company-wide system, which was the whole point of building it that way.

  • 35+ flows delivered against a library built mid-project
  • Project completed in about half the expected time
  • Design-to-development handoff streamlined
  • Sub-library merged into the company-wide design system
  • Shipped, then adapted for further colleague groups