Reusable components are a great way to build a performant and consistent UI for your applications, without having to reinvent the wheel. Components can save time, speed your development, simplify maintenance, help standardize your stack, and keep a consistent UI design system.
A common questions is, what’s the best way to construct and manage these components. Facing the overhead of maintaing dozens of repos, many teams turn to a component library. Pinterest uses Gestalt, Shopify uses Polaris and so on. GitHub has many great libraries to offer, from React to Vue and more.
Let’s review 5 points to consider when building your library. I’ll also explain the values of different tools such as Bit, our own OSS project built among other things for this purpose, as well as tools like StoryBook and Lerna.
Let’s dive in.
Reusable components can speed your app’s development, dramatically.
But, grouping reusbale components in a library can also create a pitfall that can slow down future development. This happens when every change to a component has to go through the library’s source repository and its owners.
This happens because a component library is a little bit like a music CD-Rom. If you want to modify a piece of it, you’d have to access the original repository, make change, and re-publish the whole project.
This process can impair the adoption of your libraries, as developers may hesitate to use them knowing they will have to go through the source repository and its owners to make even the slightest change.
This in turn can lead to more re-implementations of the same components, which the organization’s infrastructure team will somehow have to manage. As a result, instead of having developers adopt the library you’ll end-up having to enforce it. This can be a tough road to travel.
To make the library easier to adopt, it’s important to enable its consumers to make changes when they’re needed.
For example, some compnaies group components into different libraries for different teams or for different themes. When your team owns the repo, it’s easier to make changes. However, over time, you might end up with multiple libraries containing overlapping components with slight differences.
In my (subjective) view, this problem can be solved using Bit. Adding Bit to the library doesn’t require any refactoring, and makes every component available to discover, install and even develop from any other project.
Changes to components can be synced between projects (updates, cross-repo merge etc..) while kept under control. Here’s an example React app, and its matching component collection, and a short video demo.
Reusable components are a great way to build a consistent UI design system.
A consistent UI makes people “feel at home”, reducing user confusion while increasing user loyalty and satisfaction when interacting with your product.
Reusbale components are a healthy way to build a consistent UI, as a part of a larger design system, as they can provide both visual and functional consistency to help users navigate and interact with elements in your UI.
A component library is a great way to build this consistency, as it helps to create a UX/UI standard across different parts of your apps or different apps. It’s also an effective way for designers to introduce consistent guidelines.
However, to help developers adopt these guidelines it’s important to leave them some room to play without breaking the rules.
Not every style should be reusbale and pre-defined (e.g. component relative margins). When building your library, remember that a balanced collaboration between developers and designers is the key to real adoption.
If you make the library’s components available with Bit, every component can be interactively visualized (example) so that developers can view and play with it before choosing to install or import it.
The important thing to remember is, consistency is a principle and not an absolute value. When building your library leave some room to play. If you won’t, people might have to break the rules to get the job done.
A component library is easier to maintain than dozens of different repositories for different components. It’s also a great way to standardize your technological stack and avoid redundant dependencies.
For example, imagine a component copy-pasted or rewritten in 5 different repositories. Every change would require making changes in 5 repos and working through their different dependency graphs. Sounds bad, right?
Now, imagine that one component is tested with Karma while another one uses Jest. Pretty soon, you’d lose control and grow a painful debt in your codebase. You really want to avoid that.
Building a component library standardizes the technological stack around your components, and lets you better control changes and modifications.
To make maintenance even more effective, you can leverage Bit to create a distributed process in which component changes can be made by any authorized developer from any project or app they’re working on.
Reusable components improve performance and reduce the bundle size of your app, as they remove the redundant and duplicate code it will have to run.
However, libraries can also bloat your application as you have to add an entire library even when using a single component. In some cases, you’ll even have to add multiple libraries to a single application.
Ideally, you’d like to install the components you need- and nothing else.
With Lerna, you can turn your library into a multi-package “monorepo”. However, this requires massive refactoring and will eventually force you to keep dozens of packages within the repository, with all their configuration files, dependency trees etc..
With Bit, you can effortlessly make the components from the library available to install with NPM. Thus, turning your library into a “dynamic” monorepo, without having to refactor it or manually handle component dependancies.
Another option is to combine the two, using Lerna to publish core parts of your repo while using Bit to make UI components available as packages.
Discoverability is one of the biggest problems around reusbale components and modules. Every library would require a wiki, which in turn will require more maintenance. Even then, finding components remains a challenge.
Within the organization, this problem can get even worse as you’d have to somehow maintain and dig through multiple wikis just to learn if the components you need even exist in a library somewhere.
Some organizations try to build “discovery platforms” for their components, some use StoryBook or Styleguidist and others rely on wikis. Our team uses Bit to organize over 250 components/modules (Node.js and React) into collections and make them discoverable to find and use at once.
Every component can be found via a component search engine, and they’re presented with visual interactive rendering (for UI components), tests and build results (which Bit runs in isolation) and auto-parsed docs, making it easier to find and choose the right components based on useful information.
Reusable components are a great way to speed the development process of your applications, improve performance and keep your UI consistent.
A component-library is a common go-to option for grouping these components, which eliminates the overhead of keeping dozens of repos. However, component libraries can also introduce some pitfalls, which can be avoided using the right thinking, tools and methodologies.
Here is a short recap of the key points to keep in mind.
- Dev Velocity: Don’t impair the library’s adoption, enabling developers to collaborate and evolve the components.
- Consistency: Keep consistency but leave room to play when possible.
- Maintenance & Standardization: Unify your tech stack and simplify maintenance through smart architectures and tooling.
- Performance: Don’t use cross-libraries whenever possible, use individual components instead of the whole library.
- Discoverability: Leverage discoverability platforms to help developers find and use the components they need.