Variant

Concept

A set of differing forms of one component, defined along named axes so that a single component can present several appearances.

Why it exists

Every product ends up with the same part looking slightly different from screen to screen. The save button and the invite button differ by two pixels in height, and the cancel button's gray comes in two shades. Nobody did anything wrong; each one was copied from a nearby screen and adjusted. The cost arrives later, when a color changes and somebody has to decide which of the grays was deliberate.

Pagedeck's design file was in that state. Noa counted the shapes named "button" and found 27, of which five were genuinely different in purpose. The other 22 were copies, and nothing in the file said which one was the reference. Theo's side looked similar: button styles were written per screen in the code, and changing a color meant editing nine places.

A variant folds that into one part. Instead of 27 buttons there is one button, carrying axes like purpose and size, and picking a value on each axis produces the appearance you want. The file holds one button, and screens use that one with different axis values. None of the shapes changed; what changed is that there is now one place to change them.

How it works

Axes get defined on a component, and each combination of axis values is one variant. Five steps.

  1. Decide the axes. For a button, purpose and size are the common two. Purpose values are things used differently from each other — primary, secondary, ghost — and size values are small, medium, large.
  2. Count the combinations. Three purposes and three sizes make nine. Add one more axis and it becomes 27. Count that before adding an axis, because the cost of an axis multiplies rather than adds. A fourth axis with two values takes 27 to 54, and every one of those has to be drawn, named, and reviewed.
  3. Keep states off the axes. Hovered, pressed, and disabled are switched by code, so making them design axes only inflates the count. Disabled is the usual exception, since its color and its label change together, so most teams draw it out explicitly.
  4. Match value names to the code. Call it "emphasis" in the design file and primary in the code and every meeting needs a translator. Settle on one set of names and record it in the component spec, the document that lists a part's properties, states, and rules.
  5. Pick the default. It's what appears when someone drops the component in without choosing anything. Make the most-used combination the default and building screens takes fewer moves. It also means a part dropped in without thought still looks like something the system would produce.

The values that differ per axis are managed as design tokens — named units for things like color and spacing that get shared with code. Hold the primary button's background in one token and changing that token changes every primary button. Variants define which appearances exist; tokens hold the values those appearances use. Keeping the two separate is what lets a rebrand happen without editing a single variant definition.

Where it shows up

The first place is publishing a part into a component library, the collection of the parts that make up screens. Anything published there has to declare which forms a user of it may choose. Without axes and values, people go back to copying and adjusting, and within six months the file is where it started. Publishing without axes publishes a suggestion rather than a part.

Three other places.

  1. Matching the code — a design axis becomes a property. The purpose axis becomes a kind property, and the values become what gets passed to it. When the two map one to one, an engineer reads the design and knows what to pass.
  2. Review — when a new screen contains an unfamiliar button, the question in review is fixed: can this be made from existing axis values, or does it need a new axis? If it needs one, the count of combinations that one screen adds gets looked at too.
  3. Cleanup — sorting accumulated copies by axis. Line 27 up against nine combinations and most fall into the same cells; the few that fit no cell are the genuinely new forms. Those are worth a conversation; the rest get deleted without one.

Some things don't belong here. A shape used once on one screen doesn't become an axis. Neither does an axis with a single value. An axis added because more values seem likely later only raises the combination count and explains nothing.

How it sounds at work

"I think this is a variant of the existing button rather than a new one."

Check whether a combination of axis values solves it first.

"One more axis takes us from nine combinations to 27."

Adding an axis costs a multiplication.

"Name the variants exactly what the code properties are named."

Remove the translation step between design and code.

Noa folded the 27 buttons into one. The purpose axis got three values — primary, secondary, ghost — and the size axis got two, medium and small, for six combinations. Three copies fit no combination; each had been used on exactly one screen, so they stayed on those screens rather than becoming axes.

Theo moved the same axes into code properties. After that, changing the primary button's color meant editing one place instead of nine.

What people get wrong

The most common belief is that more variants make a more flexible system. With many appearances to choose from, any screen seems coverable. But more combinations make choosing harder. When working out which of thirty combinations fits takes time, people copy something close and adjust it instead — and at that moment the system is back to where it was before it existed. Before adding a value, separate whether it's a genuinely different use or the same use in a different shape. A library of twelve well-chosen combinations gets used more than one of forty.

Putting states and variants on the same axis is also common. A hovered button is a form of the button, so it gets added as a value. But states are switched by code in response to a user, and variants are chosen by whoever builds the screen. Mixing them multiplies the count by the number of states, and engineers don't use those values anyway. Primary and secondary are chosen; a hovered primary button is not. The test is short: if code decides it at runtime, it isn't an axis.

Easily confused with

TermWhat it refers toHow it differs
InstanceA copy of a source component placed on a screenA variant is the list of forms the source offers; an instance is one placement of that source. Five primary buttons on one screen are five instances of one variant. Changing axis values on an instance is normal, but hand-editing a color that no axis covers detaches it from the source, and it stops receiving updates

Where to go next

Last updated 2026-09-16