What is a component contract?
A prop type says what a component accepts. A contract says what it must never do — and writes that down where an AI agent can read it.
A component contract is the agreed specification of a single UI component — its inputs (props), its states, the design tokens it is allowed to use, its accessibility requirements, and its do's and don'ts — written in a form that both humans and AI coding agents can read.
It defines not just how a component looks, but the boundaries within which any implementation of it must stay. When a component has a contract, a human, a teammate, or an AI agent can rebuild or extend it without silently violating the design system — because the rules are explicit rather than remembered.
It is not a prop type, and not a Storybook story
You may already have a TypeScript interface for ButtonProps and a story that renders every variant. Both are useful and neither is a contract. A prop type says what the component accepts; a story shows what it can look like. A contract adds the thing neither of them carries: the boundary it must not cross — “primary background is never anything but the accent token,” “this component has exactly these four states and no others,” “focus is always visible.”
That idea is borrowed from API contracts, where the agreement — not the implementation — is the thing everyone codes against. A component contract brings that discipline to the surface of your UI.
Why implicit contracts break under AI
Every reusable component already has a contract. Usually it lives in a designer's head, a reviewer's judgment, and a paragraph of docs — an implicit contract, carried by memory. That works until the thing reading the component is not a person who was in the room.
An AI agent was never in the room. When Claude Code or Cursor regenerates a component, it does not know which tokens are allowed, which states are legitimate, or which accessibility rule is non-negotiable. It can read the prop types — but “never use color.signal as a button background” is a design prohibition that does not appear in a type. So the agent invents a fifth state you never had, or reaches for a color that looks close. A violation, compounded across components, is exactly what design token drift looks like at close range.
Making the contract real
A contract only works if the same one is read by everyone who builds the component — the human in review and the agent at 2 a.m. Three things make it real:
- Write down the allowed tokens, states, a11y rules, and do/don'ts for each component — not just its props.
- Keep it in a machine-readable single source that humans and agents read from the same place.
- Check implementations against it — flag not only bad props but tokens and states that step outside the boundary.
In Harnd, each component spec is a contract with a stable ID (cmp_), so a human and an agent implement against the same agreement, and any step outside it is caught by a quality gate rather than by luck.
The unit of a design system is the contract
It is easy to think the unit of a design system is the component. It is not — the unit is the agreement. What gets reused is not the code; it is the shared understanding of what the component is allowed to be. Without that agreement written down, a component library is just a collection of shared misunderstandings, each copy slightly more wrong than the last.
Type systems made a program's contracts machine-readable. Component contracts do the same for design decisions — which matters now that an AI agent is a first-class implementer of your UI. The intent has to travel as a contract, not as a memory. For the whole layer that holds tokens, contracts, and quality gates in one source, read what a design harness is.
Want your components to have a contract your agents can actually read? Get early access.