Variant, or a new thing
The question that comes up every week
Somebody needs a button that is smaller, has an icon, sits on a dark background and is used for a destructive action. Is that a variant of the existing button, or a new component?
Getting this wrong in one direction produces a library of ninety components that are all nearly the same. Getting it wrong in the other produces one component with forty properties that nobody can use correctly.
The test that resolves most cases:
Same structure and same purpose, different appearance or emphasis → variant.
Different structure or different content model → new component.
A small destructive button has the same structure as a large primary one — a container, an optional leading icon, a label — and the same purpose, which is to trigger an action. Variant.
A card that contains an image, a title and three metadata rows has a different content model from a card that contains a paragraph and a link. Those are two components, even though both are rectangles with padding.
Axes, not permutations
A button with 4 appearance variants, 3 sizes, 8 states and an optional icon has 4 × 3 × 8 × 2 = 192 combinations. You cannot draw 192 buttons, and you should not try.
What you define instead is the axes and the rules for each axis:
variant: primary | secondary | ghost | danger
size: sm (32px) | md (40px) | lg (48px)
state: default | hover | focus | active | disabled | loading
icon: none | leading | trailing | icon-onlyThen document how each axis behaves independently, and draw only the combinations that are genuinely non-obvious — usually icon-only, disabled, and loading, because those change the structure rather than just the colour.
This is also the argument for keeping the axis count low. Every new boolean property doubles the space. A component with nine boolean properties has 512 configurations, most of which nobody has ever looked at, and several of which are certainly broken.
Slots keep the count down
The technique that prevents most component sprawl: give a component a slot — a region that accepts arbitrary content — rather than a property for every possible piece of content.
A card with a header slot, a body slot and a footer slot serves fifty layouts. A card with title, subtitle, imageUrl, badgeText, badgeColour, metaLine1, metaLine2, ctaLabel and ctaHref serves exactly one, and the next requirement adds a tenth property.
The trade-off is real: slots give up control, so a card with a free body slot can contain something that looks wrong. The usual resolution is slots for layout regions and properties for the things the system genuinely wants to govern, such as the card's own padding and elevation.
Anatomy: name the parts
For every component, name its parts. This sounds like bureaucracy and it is what makes the conversations possible.
Button anatomy: container · leading icon · label · trailing icon · focus ring
Field anatomy: label · control · hint · error message · required marker
Card anatomy: surface · media · header · body · footerWith names, a review comment can be the gap between the leading icon and the label is 4px and should be 8. Without them it is the icon thing looks squashed, which produces a different fix each time.
Signs a component should be split
- It has a property that changes several other properties' meanings.
- Half its properties are only valid when another property has a particular value.
- People keep detaching or copying it instead of using it.
- Its documentation needs the word except.
- Its name contains and.
That last one is reliable enough to be a rule of thumb. SearchAndFilterBar is two components.
Signs it should not have been split
The opposite failure is just as common and harder to see, because a large library feels like progress.
- Two components with the same anatomy and different colours.
- A component used exactly once, ever.
- Three components that were copied from each other and have since drifted.
The audit: list every component and its usage count. The ones used once are candidates for deletion or for merging back into whatever they were copied from. A library where a third of the entries are used once is not a system; it is a folder.
The one thing to keep
Make a variant when the structure and purpose are the same and only the appearance differs, and a new component when the content model differs — then define axes and rules rather than drawing permutations, and use slots to keep the property count from doubling.
Before you move on
A card component has accumulated properties: title, subtitle, imageUrl, badgeText, badgeColour, metaLine1, metaLine2, ctaLabel and ctaHref. A new design needs a card with a chart in place of the image. What is the better response?
Pick the one you would defend. Nobody sees your answer.