Loading...
Design SystemsArchitectureEngineeringFrontend

The Component Library Trap

The Component Library Trap Featured Image

The Component Library Trap

Why "Building Your Own" is almost always a mistake, until it isn't.

It starts innocently enough. You need a button. The designer has cooked up a beautiful primary action button with a specific border radius, a subtle gradient on hover, and a shadow that Material UI just doesn't support out of the box.

"I'll just make a quick `Button` component," you say. "It's just a div with an onClick handler. How hard can it be?"

Three months later, you have a team of four engineers whose entire existence is dedicated to maintaining `datepicker.tsx`, debating the merits of controlled vs. uncontrolled inputs, and patching accessibility violations in your custom modal implementation.

Welcome to the Component Library Trap.

The Illusion of "Simple"

The fundamental error we make as frontend engineers is underestimating the complexity of standard UI elements. A native HTML <button> is a miracle of engineering. It handles focus states, keyboard navigation (Tab, Enter, Space), form submission behavior, disabled states, and accessibility announcements for screen readers.

When you replace it with <div className="btn">, you are opting out of decades of browser evolution. You are now responsible for reimplementing every single one of those behaviors. And you will forget half of them.

Building a component library isn't about styling. It's about API design and edge-case management.

Take the humble dropdown menu.

  • Does it close when you click outside?
  • Does it close when you press Escape?
  • Can you navigate the items with arrow keys?
  • Does it handle screen boundaries correctly (rendering up instead of down if near the bottom)?
  • Does it trap focus while open?
  • What if the items are async loaded?

Suddenly, your "simple" dropdown is 400 lines of code and has three open bugs.

The "Not Invented Here" Syndrome

Why do we do this? Often, it's a mix of hubris and a desire for control. We look at existing libraries like Radix UI, Headless UI, or even heavyweights like MUI and Ant Design, and we see bloat. We see props we don't need. We see DOM structures we don't like.

"I want something lightweight," is the rallying cry.

But "lightweight" is often a euphemism for "feature-incomplete." Existing libraries are heavy because they handle the edge cases you haven't thought of yet. They handle right-to-left languages. They handle reduced motion preferences. They handle high contrast modes.

The Maintenance Tax

Every line of code you write is a liability. A custom component library is a massive liability. It requires documentation, testing, and constant updates as browser standards change.

If you are a product company, your core competency is your product, not your datepicker. Every hour spent fixing a z-index bug in your custom tooltip is an hour not spent improving your actual product.

The Middle Ground: Headless UI

For years, the choice was binary: use a bloated, opinionated framework (Bootstrap, Material UI) or build from scratch. But the rise of "headless" UI libraries has changed the equation.

Libraries like Radix UI, React Aria, and Headless UI provide the logic and accessibility primitives without the styles. You get the robust engineering of a battle-tested library, but you retain full control over the CSS.

This is the sweet spot. You aren't reinventing the wheel; you're just painting it.

When Should You Build?

Is it never okay to build your own? Of course not. There are valid reasons:

01.

Unique UX Needs

If your product interacts in fundamentally novel ways (e.g., a canvas-based design tool, a complex data visualization dashboard), standard components might not fit.

02.

Scale

If you are Google, Facebook, or Spotify, the economies of scale might justify a dedicated design systems team. Most of us are not Google.

For the rest of us, the path is clear: Stand on the shoulders of giants. Use headless libraries for the hard stuff. Write CSS for the brand stuff. And please, for the love of the web, don't try to write your own datepicker.