TL;DR
- Most shared libraries are built to prove engineering maturity, not to solve an adoption problem. That goal mismatch is what kills them.
- Ownership that belongs to everyone belongs to no one. Without a dedicated team and a clear success metric, the library drifts.
- Teams build their own button because it is faster than dealing with a library that does not quite fit. That is a process failure, not a discipline failure.
- The libraries that survive are designed around the consuming team's workflow, not the library team's architecture.
The familiar arc
It usually starts after the second or third time a senior engineer notices the same dropdown built three different ways across three different products. Someone says the thing everyone has been thinking: "We should have a shared component library." Everyone nods. A project gets funded. Engineers are pulled in. A Figma file appears. There are meetings about design tokens.
Six months later, the library exists. It has a Storybook. It has documentation. It gets presented at an all-hands. The demo goes well. People clap.
Twelve months after that, teams are quietly building their own versions of the same button component.
I have watched this happen across more than one organization. One codebase I worked in had a shared button component that was technically "the standard." It also had three product-specific button wrappers built on top of it, each one started to handle a small exception: an icon placement the library did not support, a loading state that needed different timing, a size variant the design team added after the library shipped. Each wrapper made complete sense at the time. A year later, nobody could agree on which button was actually the standard, and new engineers had to ask around to figure out which one to reach for.
The pattern is consistent enough that I think it is worth looking at why it keeps happening, because it is not random and it is not bad luck.
The goal was completeness, not adoption
The first problem is what the library is optimized for. In most organizations, the implicit goal of a shared component library is completeness. Cover all the common components. Get to the point where you can say you have a design system. Ship it.
Adoption is treated as a downstream consequence. Build it right, the thinking goes, and teams will use it.
But adoption is not a consequence of correctness. It is a consequence of the library being easier to use than the alternative. And the alternative is always available: just write the component yourself. You already know how to do that. You have done it a hundred times. The library, on the other hand, requires learning a new import pattern, reading documentation that may or may not be up to date, and figuring out how to make the component fit a design that is slightly different from the one the library was built against.
When the path of least resistance is to roll your own, most engineers will roll their own. Not out of stubbornness. Out of time pressure and the rational desire to ship.
“Adoption is not a consequence of correctness. It is a consequence of the library being easier to use than the alternative.”
Who owns it, really
The second problem is ownership. Shared component libraries often start as a side project owned by whoever had the original energy for it. That person has a real job. After the launch presentation, the real job takes over.
At some point the library becomes "owned by everyone," which means owned by no one. Pull requests sit open for a week waiting for a review from someone who is heads-down on a product deadline. Bug reports get filed but not triaged. Component requests come in and go nowhere because there is no one whose job it is to prioritize them.
Without a person or team whose success metric is whether consuming engineers are actually using the library, the library drifts. It gets updates when someone cares enough to push one through. It does not get retired when a pattern no longer makes sense. Features accumulate without a coherent rationale.
A library that is nobody's job ends up in a state that is nobody's fault and everybody's problem.
What actually works
The libraries I have seen survive have a few things in common, and most of them are not technical.
The first is that someone's job depends on adoption, not just existence. There is a person or a small team whose success is measured by whether consuming teams are actually using the library, not by whether components have been added to it. They sit with the consuming teams. They watch where engineers get stuck. They treat a workaround as a bug report.
The second is that adoption is tracked like a real metric. Healthy library teams know what percentage of applications in the organization consume the library. They know which components are used most, which teams are bypassing it and why, how long it takes to fulfill a component request, and how often a new team ships their first component in under a day. These numbers do not have to be perfect. They just have to exist. Visibility is what creates accountability, and right now most teams have no idea whether their library is actually being used until someone complains.
The third is that the consuming teams had a say in what got built. The worst libraries are built in isolation by people who guessed at what other teams would need. The ones that stick are built in close collaboration with at least one real consuming team, often shipping the library and the first real usage at the same time. Nothing surfaces design problems faster than a real use case. When a consuming team hits a wall, the library team treats it as a priority, not a backlog item.
The fourth is that the developer experience is treated as a product. How long does it take to install and use the first component? Is there a single command that gets a new team to their first rendered button? Can engineers search by what they want to build, not just by component name? The library that wins is the one that respects how much time engineers are willing to spend learning something new before they decide it is not worth it. Time-to-first-component is a metric worth tracking as seriously as bundle size.
And the last one is the hardest to say because it sounds simple: start with fewer components, but make those components work in every real scenario the consuming teams actually have. A library with five components that fits perfectly is more valuable than a library with fifty that requires a workaround on every third use.
The honest version
Shared component libraries are not an engineering problem. They are a prioritization problem wearing an engineering disguise.
If the library does not have dedicated ownership, it will drift. If the consuming teams were not involved in the design, it will not fit. If adoption is not tracked as a real metric with real consequences, nobody will notice when the library stops being used.
The teams that get this right do not have better engineers or better component APIs. They have made an organizational decision that the shared library is a real product with a real team behind it, and they hold that team accountable to whether engineers actually use it.
The question is not whether your organization needs a component library. The question is whether it is willing to fund and operate one like a product, with dedicated ownership, success metrics, and a team that treats consuming engineers as customers. If the answer is no, the library will eventually become another abandoned dependency that every team quietly works around. That is not a failure of engineering. It is the predictable outcome of treating a product problem like a project.
“If adoption is not tracked as a real metric with real consequences, nobody will notice when the library stops being used.”
Thanks for reading.
If this resonated and you're hiring for Senior/Staff Frontend roles, I'd love to chat.