practice

Component Contracts

The interface a shared UI component presents — where the discipline is refusing options as much as providing them.

design-systemcontractsversioningaccessibilityconsistency

Definition

A component contract is the agreement between a shared component and its consumers: the props it accepts, the behaviour it guarantees, the events it emits, and the styling it permits.

What a good contract looks like

  • A small, purposeful prop surface. Every option is permanent surface area, and options interact combinatorially.
  • Semantic rather than presentational props. variant="danger" rather than color="red" — so the design system can change what danger looks like without touching consumers.
  • Composition over configuration. Slots that accept children beat twenty boolean flags, and they accommodate cases the author did not anticipate.
  • Accessibility guaranteed by the component, not left to consumers. Keyboard behaviour, focus management and ARIA semantics belong inside; if each consumer must get them right, most will not.
  • Controlled and uncontrolled modes stated explicitly, since ambiguity here is a recurring source of bugs.
  • Documented breaking-change policy, because a shared component has consumers you cannot enumerate.

The discipline that matters most

Say no to props. Every option added is permanent: it must be tested, documented and supported forever, and it multiplies the combinations that can occur.

A component with thirty props has usually absorbed several distinct components. The healthier response to a consumer needing something different is frequently a second component, or composition — not another flag.

Versioning and change

A shared component library is an API with internal consumers. It needs:

  • Semantic versioning with a real breaking-change policy.
  • Deprecation warnings in development builds, so consumers see them where they work.
  • Visual regression testing, because a CSS change can break consumers in ways no unit test catches.
  • A migration path for breaking changes, ideally with a codemod.

Failure scenarios

  • Prop explosion, so the component is unmaintainable and its behaviour unpredictable.
  • Presentational props, so the design system cannot evolve.
  • Accessibility left to consumers, so it is inconsistent and mostly absent.
  • Breaking changes without notice, since consumers cannot be enumerated.
  • No visual regression testing, so styling changes break consumers silently.

Interview question

"A team asks for a new prop on a shared component. When do you say no, and what do you offer instead?"