Eighteen months ago, we decided to build a shared component library for our enterprise projects. At the time, every project had its own buttons, its own form inputs, its own data tables. Three projects running concurrently meant three different implementations of the same patterns, each with different bugs, different accessibility levels, and different maintenance needs. The component library has since become the single most impactful investment we've made in delivery speed.
What You Need to Know
- A shared component library reduced our frontend development time by approximately 30-40% across projects
- The initial investment was significant: three months of dedicated work before the library was usable
- The biggest benefits aren't speed - they're consistency and accessibility baked into every component
- The hardest part isn't building the library. It's governing it so it stays useful.
Why We Built It
The trigger was a code review. Rainui was reviewing a data table component on a new project and noticed it was missing keyboard navigation. He checked the data table on our other active project. Also missing keyboard navigation. He checked the third project. That one had keyboard navigation but no sort functionality.
Three projects. Three data tables. Three sets of bugs. Three sets of maintenance. The components weren't just inconsistent visually. They were inconsistent in capability.
67%
of design system teams report reduced development time after adoption
Source: Sparkbox Design Systems Survey, 2020
The calculation was simple. We could keep building one-off components for each project and accepting the inconsistency, or we could invest in a shared library once and use it everywhere. The upfront cost was high. The ongoing savings were obvious.
What We Built
We started with the components that appeared in every enterprise project:
- Button (with loading state, disabled state, icon support)
- Form inputs (text, select, checkbox, radio, date picker)
- Data table (sortable, filterable, paginated, keyboard navigable)
- Modal and dialog
- Toast notifications
- Navigation components (sidebar, breadcrumb, tabs)
Each component followed the same specification:
- Fully accessible (WCAG 2.1 AA)
- Keyboard navigable
- Responsive
- Themeable via design tokens
- Documented with usage examples
The component library isn't a UI kit - it's an accessibility guarantee. Every component carries hundreds of hours of accessibility work developers never have to redo.
Rainui Teihotua
Chief Creative Officer
The Mistakes
Starting Too Big
Our first attempt included 40 components. Too many. Half of them weren't needed across multiple projects. We spent weeks building a stepper component and a timeline component that one project used. The overhead of maintaining components that aren't widely used exceeds the cost of building them per-project.
We scaled back to 18 core components. Everything else is built per-project until it appears in three or more projects, at which point it graduates to the library.
Premature Abstraction
We tried to make every component infinitely flexible. The Button component had fourteen props. The data table accepted custom renderers for every cell, header, and row. The flexibility made the components hard to use. Developers spent more time reading documentation than they saved by using the library.
John rewrote the core components with opinionated defaults and fewer configuration options. A button has size, variant, and a few behavioural props. If you need something the library doesn't support, build it locally. The library should handle 80% of cases perfectly, not 100% of cases awkwardly.
No Versioning Strategy
We didn't version the library initially. Changes to a component affected every project immediately. When we improved the data table's sort behaviour, it broke a project that depended on the old behaviour. After two incidents like this, we implemented semantic versioning. Projects pin to a version and upgrade deliberately.
The Outcome
After eighteen months, the numbers tell the story.
Frontend development speed improved by approximately 35% for new features. Developers spend less time building basic UI components and more time on business logic and user experience.
Accessibility compliance improved from inconsistent to reliable. Every component in the library passes automated accessibility testing. Every project that uses the library inherits that compliance.
Visual consistency across projects improved dramatically. A RIVER-built application looks like a RIVER-built application, regardless of which developer built which screen.
Onboarding time for new developers decreased. The library documentation serves as a pattern guide. New developers learn the conventions by reading component examples rather than reverse-engineering existing code.
The component library's biggest value isn't the components - it's the shared vocabulary. When a developer says "use a data table with server-side filtering," everyone knows exactly what that means.
John Li
Chief Technology Officer
Advice for Teams Starting Out
Start with fewer components than you think you need. Build the ten components that appear in every project. Add more only when the need is proven across multiple projects.
Invest in documentation early. A component without documentation is a component nobody uses. Each component needs: props documentation, usage examples, accessibility notes, and "when to use this vs. when not to."
Assign ownership. Someone needs to be responsible for the library. Without an owner, it decays. Components stop getting updated. Documentation falls behind. New patterns get built locally because the library feels stale.
Accept that it's never done. A component library is a product, not a project. It evolves with the needs of the projects it serves. Budget ongoing maintenance time, not just initial build time.
The investment paid for itself within two projects. If your team builds enterprise applications and doesn't have a shared component library, the question isn't whether to build one. It's how soon you can start.

