Skip to content
Design/component-decisions

Not everything that looks the same is the same thing.

"Decide when a UI pattern becomes a component and when it stays a one-off."

Authored by:Ali AhmedAli Ahmed

Why this exists

Premature componentization is as bad as none at all. I have seen codebases with forty-seven button variants because someone abstracted too early. I have also seen projects where every modal was rebuilt from scratch because nobody checked if this was the third time. Both failures cost time and money. This rule gives you a threshold before you reach for either extreme.

Operational Flow

1

Count occurrences: Before proposing a component, find three distinct places in the project where it already exists or is definitely needed.

2

Name it precisely: If you can't write a one-sentence description of what the component does without the word 'and', split it.

3

Audit props early: Document every variant the component must support on day one. Variants discovered later cost twice as much to add.

4

Check the design system first: Search Figma and the codebase for an existing pattern. If nothing fits in three minutes, it doesn't exist.

5

Write the usage example first: Sketch how the component will be called in code or placed in Figma. If the interface feels awkward, the component is wrong.

6

Flag deprecation risk: If you build a component for a single client feature, mark it as project-scoped. Don't migrate it to the shared system without a deliberate review.

What good looks like

  • A designer proposes a StatusBadge component and provides a Figma frame showing all four states (success, warning, error, neutral) before writing code.
  • An engineer finds a second use case for a component and opens a PR that adds exactly one new prop, documented and typed, instead of copy-pasting the implementation.
  • The shared library has under thirty components, and every single one is used in at least two places in production.

What NOT to do

  • Don't create a component because the design looks similar. Check whether the underlying behavior and data shape match.
  • Don't add props to a component to handle a one-off edge case. Build a wrapper or a separate component instead.
  • Don't ship a component without a usage example in Storybook or an isolated view. Undocumented components get misused within a week.

The most expensive component we ever built was a universal card. We designed it to handle eight different content types across three client projects. By the time the fourth project touched it, the component had twenty-two props and a seventeen-line conditional render. Nobody wanted to change it because nobody understood it. It wasn’t bad engineering at the start; it was just an abstraction that grew faster than our reasoning.

You earn component status by appearing three times with the same behavior, not just the same shape. Visual similarity is a clue, not a verdict. When in doubt, copy the code and wait. Duplication is easy to reverse. A bad abstraction is a six-hour refactor waiting for the worst possible week.