Building a UI Library Is Just the Beginning
From Reusable Components to Sustainable Design Systems
The Story Doesn’t End with Reusability
Sharing components does not necessarily mean sharing design decisions.
When I first started working on a shared UI component library, much of my attention was on reusability, consistent APIs, and reducing duplicated development effort. These were important goals, and they still are.
In a previous article, I explored why building a shared UI library matters. But as I spent more time working with shared components across different products, I started questioning whether reusing the same components was enough to create a consistent user experience.
Different teams naturally had different expectations. Some needed additional features, others wanted to customize existing components, and occasionally a requirement made perfect sense for one product but felt out of place in a shared library.
None of these situations was necessarily a problem on its own. In fact, they often came from legitimate product needs. What interested me was the question behind them: How do we decide what should be shared, and what should remain specific to a product?
I gradually realized that having a common implementation does not always mean having a common understanding of how that implementation should be used.
This is where I started thinking beyond the component library itself.
Beyond the Component Library
A component library gives developers reusable building blocks. A design system goes further by connecting those components to shared design principles, visual foundations, interaction patterns, and usage guidelines.
Consider something as familiar as a Button. A library might provide primary and secondary variants, but that alone does not tell teams when to emphasize an action or how to establish a consistent hierarchy across different interfaces.
Those decisions matter to users, even if they never notice the underlying components.
Accessibility is another example. A component can provide keyboard support, semantic behavior, and focus handling, but whether an entire workflow is accessible also depends on how components are used together. Shared guidelines can help teams make more consistent choices, although accessibility still needs to be validated within each application.
This broader perspective is visible in established systems such as IBM Carbon, which brings together foundations, components, and patterns rather than treating reusable components as the entire solution.
Of course, a component library already contains design decisions. They are reflected in its styles, APIs, and behavior. The difference is that a design system makes more of those decisions explicit and gives designers and developers a common language for applying them.
To me, that is one of its most important contributions: not just sharing components, but sharing the reasoning behind how they should be used.
Consistency Doesn’t Mean Uniformity
One of the challenges I have noticed while working with shared components is that consistency and flexibility are not always easy to balance.
Take CSS overrides, for example.
A team may need a Button to look slightly different in its application. Another team may make a similar adjustment in a different way. Over time, the same shared component can start producing different visual conventions across products.
It is tempting to see every override as something that should be prevented. But I do not think that is the right approach. Sometimes customization is justified.
The more useful question is whether there is a shared understanding of when a difference should become a reusable variant, when an existing pattern is sufficient, and when the customization should stay within the product.
Get Melisa Nur Kart’s stories in your inbox
Join Medium for free to get updates from this writer.
The same dilemma appears in more complex components.
Imagine a DataTable that supports several applications. One team requests a specialized row action for its workflow. Should we add it to the shared API? Provide an extension point? Or let the product implement it separately?
As a developer, it is easy to focus on whether a feature can be implemented. But in a shared library, I have found that deciding whether it belongs there is often the more important question.
A design system will not make that decision for us. What it can provide is a shared foundation for evaluating the impact on interaction consistency, user needs, and other products.
Consistency should help users feel familiar with an interface, not force every product to behave identically.
Building for Sustainable Evolution
This becomes particularly important as a component library grows.
I have learned that adding a feature to a shared component is rarely just about implementing it once. A new public API also needs documentation, tests, maintenance, and potentially migration support when the component evolves.
A feature that solves one team’s immediate problem can become a long-term responsibility for everyone maintaining the library.
On the other hand, making components too restrictive can push teams toward workarounds that are difficult to maintain.
That is why I see extensibility as an important part of sustainability. Design tokens, shared interaction patterns, and accessibility guidelines establish a common foundation. Composition and carefully designed APIs can provide flexibility without turning every product-specific requirement into a built-in feature.
But good component architecture is not enough by itself.
Designers, product teams, and library developers often look at the same request from different perspectives. One may focus on the user experience, another on immediate product needs, and another on long-term maintenance.
I do not think the solution is to give one perspective automatic priority. It is to make the trade-offs visible and evaluate them together.
Is the requirement useful beyond one product? Does it introduce a new interaction pattern? Could an existing API or composition approach support it? What will maintaining the change mean in the future?
The Atlassian Design System offers an interesting example of this balance, emphasizing shared foundations while recognizing that consistency should not become an end in itself.
For me, a sustainable design system is not one that eliminates differences. It is one that helps teams make intentional decisions about those differences and revisit them as needs change.
Beyond Reusability
When evaluating a shared UI library, it is natural to look at how many components it provides or how many applications use it.
But I think a design system calls for a broader perspective.
Are teams finding fewer reasons to introduce unsupported styling overrides? Can they adopt updates without excessive migration effort? Is it becoming easier to explain why a design decision should be shared or remain product-specific?
These are not perfect measures. Fewer overrides do not automatically mean better design, and a faster decision is not necessarily a better one. Still, they can tell us something about whether the system is helping teams work together more effectively.
Looking back, I still believe building a shared UI library is a valuable step. It creates a technical foundation that teams can build upon.
What has changed is how I think about the work that follows.
The challenge is no longer just how to make components reusable. It is how to build a shared understanding of the decisions behind them, without losing the flexibility that different products need.
A component library can be built and released. A sustainable design system needs to keep evolving with the people, products, and experiences it supports.







