Skip to content

Now in the official shadcn registry directory.

Start free
Deep dive

The variant matrix, explained

One flat variant list is where design systems quietly break. Three axes, composed, is how the same button covers thirty styles without thirty exceptions.

5 min read
Share

Open most component libraries and the button has a variant prop with five or six values. It works until the day you need a soft, brand-colored, small button, and there is no seam to express that without a new one-off.

Three axes, not one list

ai2 splits the single variant list into three orthogonal axes: variant is the visual language, tone is the semantic color, size is the scale. They compose, so combinations are the point, not exceptions.

<Button variant="soft" tone="brand" size="sm">
  Save
</Button>

Thirty style pairs (five variants times six tones) across the size scale. The button covers them by composition, not by a growing list of hand-named variants.

The axis contract

  • The vocabulary is fixed: variant, tone, size, density, shape, orientation. No synonyms.
  • A given size is pixel-identical across every form control, so rows line up.
  • Adding a value never changes existing defaults, so upgrades are safe.
A design system earns the name when the combinations are the product, not the edge cases.

Why it holds up

Because the axes are semantic tokens, a third theme changes nothing in the components. If a component needs a special case to re-theme, it is reaching past the contract, and that is the bug to fix.