Contracts
An interface has two contracts, and collapsing them into one produces a document neither side can use.
Both are established assets. They exist before any particular feature does, they are owned and versioned, and a feature consumes them. That is the distinction the rest of this section turns on.
One agreement, written in two languages, sitting above the work rather than coming out of it.
The two
Section titled “The two”| Design system | Core component library | |
|---|---|---|
| Kind | Visual contract | Technical contract |
| Answers | What may this interface be made of? | What may code call, and what does it guarantee? |
| Owned by | Design and engineering jointly | The library team, with its consumers |
| Written as | Roles, scales, states, guarantees | Props, states, accessible behaviour, tokens consumed |
| Lives in | A Figma library and a token source | A versioned package, with a story per state |
| Breach looks like | A hex code in a component | A screen forking a component to add a prop |
| Enforced by | Lint rules, generated tokens, contrast checks | Type checking, interaction tests, accessibility scans |
Inputs to the work, not outputs of it
Section titled “Inputs to the work, not outputs of it”The contracts go into story mapping and example mapping. They are not what those sessions produce.
That single reversal is what makes the sessions fast rather than slower:
| In the session | With the contracts as inputs | Without them |
|---|---|---|
| “What does this look like when the list is empty?” | The system already has an empty state — ten seconds | A design task, scheduled, and probably skipped |
| “Can we slice the release here?” | Yes; the pieces exist, so the slice is composition | A guess, because nobody knows what has to be invented |
| “How long is this story?” | An estimate about assembly | An estimate about invention, which is not an estimate |
| “Do we need a new component?” | Usually no, and the library says so | Usually yes, and a fifth button gets written |
A team that treats the design system as something each feature produces rebuilds it per feature, slightly differently each time, and calls the result inconsistency. It is not inconsistency; it is the absence of an input.
Why “core”
Section titled “Why “core””The library is the core set: the shared, versioned components that every product in the estate builds from. It is deliberately not everything on every screen.
| Layer | Owned by | Example | Changes by |
|---|---|---|---|
| Core library | The library team | Button, TextField, Table, Dialog | Contract change request, with deprecations |
| Product composition | The feature team | A checkout summary assembled from the above | Freely, per feature |
The line between them is a useful thing to be able to draw in a session. A team composing from the core is going fast; a team adding to the core is doing a different, slower, more consequential piece of work — and it should know which one it is doing.
The direction between them
Section titled “The direction between them”Fixed, and worth stating plainly because most drift starts by ignoring it:
The design system decides. The core component library implements and enforces. Application code consumes and decides nothing.
Each arrow is one-way. A colour chosen inside a component is a fork of the design system; a spacing value chosen inside a screen is a fork of the component. Forks propagate, because the next person needing something similar copies the nearest example rather than the source.
How a contract actually changes
Section titled “How a contract actually changes”They are established, not frozen. But the route matters more than the fact.
A session finds something the contracts do not cover. A state with no designed answer, a component that does not exist, a pattern that fights the journey.
It becomes a change request, not a local invention. The story does not quietly build its own version. The request goes to the people who own the contract, with the evidence from the session attached — which is usually a state card or a usability finding.
It is decided upstream, where everyone inherits it. Accepted, it becomes part of the system and every other feature gets it for free. Rejected, the session gets a documented reason and composes from what exists.
It is versioned and deprecated properly. An addition is cheap; a change to an existing clause is a migration for every consumer. See component library on doing that without breaking six screens.
The failure to design against is the fourth outcome nobody chooses out loud: a team blocked on a change request builds its own version “for now”, and the estate acquires a second design system. A change-request path that is slow produces this reliably, which makes turnaround time on change requests a property of the contract, not an administrative detail.
When they disagree
Section titled “When they disagree”They will. A design gets built slightly differently, a component grows a variant nobody added to Figma, a token is changed on one side. Two catalogues that no longer agree are worse than one, because both sides keep citing theirs.
Keeping them aligned is that problem in full: what to check, what to automate, and which direction wins when they conflict.
What a contract is not
Section titled “What a contract is not”Not a style guide. A style guide describes; a contract constrains, and something fails when it is breached.
Not a component gallery. A gallery shows what exists. A contract says what is promised — which states, which behaviour, which props will not change without a deprecation.
Not a specification of the implementation. The test is whether the other side could change it without breaking you. If they could, it is a detail and it does not belong in the contract, however tempting.
Not a per-feature deliverable. If a story’s definition of done includes “design the button”, the button was not in a contract.
Where it connects
Section titled “Where it connects”- Contract-first is the disposition; this section is the two artefacts it maintains.
- Story mapping and example mapping are the sessions that consume them.
- Journey-first is what follows once both hold: the risk moves, so the testing does too.
- The running artefacts are on the portal: the design system and the component library.