Skip to content

Prop Naming That Survives Three Engineers and Sprints

Consistent naming for props like variant, type, and kind keeps a design system predictable. Here's how to choose names that scale, not decay into chaos.

· · 5 min read
Sticky notes with labels organized on a whiteboard representing a naming taxonomy exercise

Picture a component library with three separate props doing the exact same job: buttonStyle, buttonType, and btnVariant. Three engineers, three sprints, zero conversation. Untangling it takes most of a week nobody has.

TL;DR: Prop naming is the actual API of your design system, and inconsistency compounds fast. Modern conventions favor a single semantic variant prop over competing names like type or kind, kept separate from unrelated concerns like size, so the system stays predictable as it grows.

Photo by Jakub Zerdzicki on Unsplash

Why Does Prop Naming Matter More Than It Looks Like It Should?

Because a design system's real API isn't its visuals, it's the names an engineer has to remember every single time they use a component. Get that wrong and every consumer pays a small tax, forever. Get it right once and the tax disappears for every component built after.

A Button with variant and a Badge with type doing the identical job forces developers to look up which word applies to which component, every time, for the life of the system. That's not a nitpick. Multiply it by every engineer, every day, across years of a product's life, and it's real, measurable friction that shows up as slower PRs and more Slack questions than it should.

Variant vs Type vs Kind: Which One Actually Wins?

variant, and it's not close anymore. It's the name shadcn/ui made close to a default across the React ecosystem, paired with Class Variance Authority (CVA) to keep the values type-safe (Vercel Academy, 2026). Reserve type for genuine HTML semantics, an <input type="email"> or a <button type="submit">, where the browser already owns that word's meaning. Don't reuse it for your own style variations; you'll fight the native attribute forever.

kind shows up in older systems and it rarely earns its place. It's usually a synonym somebody reached for because they didn't check what the rest of the system already used. If you're starting fresh, pick variant. If you're inheriting kind everywhere, that's a real migration to plan, not a debate to keep having per component.

NameWhat it should meanWhen to use it
variantVisual style options (default, destructive, outline, ghost)Every component with visual style variations
typeNative HTML semantics (input type, button type)Only where the browser already owns the word's meaning
kindNo settled meaningAvoid; usually a sign nobody checked existing convention

A prop name is a promise. Break the pattern once and every engineer starts checking twice.

How Do You Keep One Prop From Doing Two Jobs?

Watch for values that secretly combine two concerns, primary-large, secondary-small, destructive-compact. That's a size and an intent smashed into one enum, and it multiplies badly: three intents times three sizes is nine values to maintain instead of two small, independent props.

Split them. variant="primary" plus size="lg" lets consumers combine values freely and lets you add a new size without touching every variant definition. The test I use on every prop review: if describing its job needs the word "and," it's already two props that haven't been separated yet.

What Does This Look Like in Practice?

type ButtonProps = {
  variant?: "primary" | "secondary" | "destructive" | "ghost";
  size?: "sm" | "md" | "lg";
  isDisabled?: boolean;
  isLoading?: boolean;
};

Notice the booleans read like yes-or-no questions: isDisabled, isLoading, never a vague state string or a negative like isNotVisible. Double negatives in conditional logic are exactly the kind of bug that slips past review, so name the positive case and flip the default instead. If your docs render prop names in a code face, monospace fonts for product UI compares IBM Plex Mono, JetBrains Mono and Berkeley Mono for that job.

Photo by jevgeni mironov on Unsplash

How Do You Stop New Components From Breaking the Pattern?

Write the convention down once, in one file everyone can find, and enforce it with a lint rule if your stack supports one. A documented convention that lives only in a senior engineer's memory doesn't survive that engineer taking a two-week vacation. This is also where a clean designer to developer handoff pays off twice: if the Figma variant names already match variant, size, and isDisabled character for character, there's no translation step where a new name could sneak in.

The same discipline applies inside Figma itself. When you build components with variants and auto layout, name the variant properties the exact same way you'll name the code props. A Figma property called "State" that maps to a code prop called variant is a mismatch waiting to cause a bug report six months from now, and nobody will remember why the two got out of sync.

My honest take: naming conventions feel like bikeshedding until you're the one untangling three duplicate props at 11pm before a release. Spend the hour agreeing on one word early. It's cheaper than every hour you'll spend cleaning up after skipping it.

What Should a New Design System Do From Day One?

Write a one-page naming contract before the first component ships, not after the third team has already picked its own convention. List the props every interactive component will share, variant, size, isDisabled, isLoading, and the exact values each one accepts. Put it next to your token documentation, not buried in a wiki nobody opens.

Then hold the line. The hardest part isn't deciding on variant over kind, it's saying no to the fourth engineer who wants buttonStyle because it's "just this one component." That single exception is how you end up back at three duplicate props a year later. A naming contract only works if it applies to the component nobody wants to slow down for too. A contract engineers route around is a design system adoption problem in miniature, and that one gets solved with fast responses and visible backing, not with a longer wiki page. You can also check the contract with numbers instead of opinions: a design system health scorecard counts how many imports and tokens actually follow it.

Frequently Asked Questions

Should I use variant, type, or kind for my component prop?
Use variant, and use it everywhere, for every component that has visual style options. The 2026 convention that shadcn/ui popularized and most component libraries have converged on treats variant as the name for visual variations like default, destructive, outline, and ghost. Type tends to get reserved for things like input type or button type (the native HTML attribute), and kind rarely earns its keep at all, it usually just means somebody didn't check what the rest of the system already used. The actual rule matters more than the specific word: whichever name you pick, every component in your system must use the same one. A Button with variant and a Badge with type is worse than either choice made consistently.
How many variants should one prop support before I split it?
Once you're stacking more than two independent concerns into a single prop, split it. A common mistake is a variant prop that secretly encodes both color intent and size, so you end up with values like primary-large and secondary-small. That's two props wearing a trenchcoat. Split it into variant (primary, secondary, destructive) and size (sm, md, lg) as separate props, and let consumers combine them freely. The test I use: if you can describe the prop's job with an 'and,' as in color and size, it's already two props that haven't been separated yet.
What's the biggest naming mistake in growing design systems?
Naming by implementation detail instead of by role. A prop called isBlueButton or hasRoundedCornersV2 describes what the component looks like today, not what it means, and it rots the moment a rebrand changes the blue. Semantic names, variant="primary" instead of color="blue", survive a rebrand because the mapping from primary to a color lives in one token file, not scattered across every place the prop gets used. I've inherited systems with a dozen near-duplicate props like buttonStyle, buttonType, and btnVariant, all doing the same job because nobody agreed on one name early. Untangling that costs weeks. Agreeing on it costs one meeting.
Do boolean props need a naming convention too?
Yes, and it's an easy one to get right: name every boolean so it reads like a yes-or-no question, isDisabled, hasIcon, isLoading, never disabled="true" as a string or a vague flag like state="1". The is/has prefix isn't decoration, it tells the next engineer at a glance that the prop is binary, not one of five enum values. I also avoid negative booleans like isNotVisible, because double negatives in conditional logic (!isNotVisible) are exactly the kind of bug that survives code review. If you catch yourself writing a negative boolean, flip the name and the default instead.