One of the great benefits of the many SPA frameworks that we use nowadays (such as Angular and React) is that it is super easy to make reusable UI components that are clean and self-contained. Components that built in these frameworks are easier to debug and far more reliable than the traditional sort of component. We can create a project with something like the Angular CLI and have a nice little directory for the components we are using in our app and it's all hunky-dory from there. If a component is not working, you simply have to make a change in one place and the problem is sorted all across your app. Now, this is great for a project where the components you have will only be used in one application. We do, however, run into some major issues when it comes to a situation where you need to use the same components for multiple, separate projects.
This is where component libraries really shine. You can have your set of components hosted on a repository like npm and whenever you need to use them in your application. The solution is simple, the method is less so. You see, it is very easy to just throw up a couple of components in an npm package and call it a day. However, if you want to have a component library that is a tool that developers love using, there are a few things that you should keep in mind.
Often times a component library becomes the sole propriety of a single developer (or at least a single team of developers) in a company. This is a big problem, especially when things go wrong. If you happen to be in a position where you are managing a component library for your company, the best thing you can do for yourself and your team is put a ton of effort into educating the people that will use the component library. Teach them about the process of creating components. Teach them about how components are named and what classifies as a component. Teach them how to even make their own components. When you do this, you are not only helping to upskill your co-workers, but you are helping them to be better equipped to implement and debug the components you create.
Don't try to protect your precious code or your knowledge. You may feel like teaching someone about the in's and out's of your job may put your own position at risk, but more often than not it will actually be a sign that you are actually good at what you do.
To build good components, you must become the components, you must think like the components... Or at least, you must get a good idea of what the components' creators thought process was when creating components. I was involved in a project not too long ago for a bank (we'll call them NextBank) where we did a complete revamp of their corporate site, design, code, the works. Because of this, we ended up creating a lot of new components. But we did this is a rather impractical way. An example of this was with the card components we created. There was not a lot of discussion with the designers (or at least not enough) through the building of the components and so by the time we started to build out pages, we discovered that we had 7 different card components, each with their own styles and use cases. However, after discovering this fact, we started actually speaking to the designers and managed to figure out what was the goal and motivation behind the design variations. We were then able to consolidate the components and even get rid of some of the completely because we were able to advise the designers about where they were creating unneeded duplication (there were a lot of cards that were only different visual, and only but a small degree).
If you want to build a good component library, make sure that you build a good relationship with your designers. Allow them to explain their thought process to you and try to understand what that want to achieve with each of the components that they have designed, and why they designed them the way they did. You'd be surprised how valid some of their rationales are. Get to know as much as you can about a component before you start to build it.
The is a line from the movie The Incredibles that I always love. The villain Syndrome is talking to Mr Incredible about how he is going to give everybody superpowers, and finishes by saying "..when everybody's super, then no one will be...". We should adopt a similar attitude towards components. Not everything needs to be a component and in fact, when you try to make everything into component, your app just becomes unmanageable. A good rule of thumb here is to wait until you see a UI pattern being used three or more times in a single application, or any number of times across more than one application. It can help to create a distinction between what I call external components and internal components. Internal components are components that are created within and applications code. They are easy to change and updated, but can only be used in the application where they have been built. Internal components can be promoted to external components at a later if you feel they meet your requirements (as in my example, if it is being used more than twice or in more than one project). Remember, internal components are easy to change and even remove because they do not have a lot of code depending on them. Try to start all your new components as internal components before making them into external components.
External components are components that are hosted outside of the project they are being used in and come with a high degree of stability and reliability. They are not going to change often, and when they do, the process is slow and easy to manage. External components will be a collection of very common UI patterns that appear across multiple projects within a brand. To go back to the example of NextBank, we had 6 different projects we were working on for them that all used the same basic set of components. It absolutely saved our lives to be able to fix bugs in one place and watch each of the projects that used the component library get fixed right away. We did, however, get to a point where everything was being made into a component in that component library (even if it only appeared in one place across all 6 projects). This made our code unmanageable and slowed down our process unnecessarily when those components need to be fixed.
Building a good component library takes a lot, and I mean a lot of planning. It's easy to build components. The trick is in building them right. Remember that when you build a component library and those components start getting used, you cannot remove them or change them drastically for fear of breaking a project's code. Even changing something as simple as a variable name can break an entire applications build system. It's wise to try to think through as many possible use cases as you can for the component you are trying to build. Make sure you know what you will call everything, how you want the component to work, how other developers will interact with it and use it, and how it will look and work on different screen sizes. Also, think about how its functionality might be changed. Will the developers who use this component be able to use it in every case they may need to use it in? Or are they going to have to hack around you code just to get it to work so that they can get the page into QA?
Think, think, think. Always ensure that your component library has a well thought out structure that will survive the tests of time and use.
There is nothing more frustrating than trying to use a component that you need only to find that is was created for a specific page and comes prepacked with copy and an image that will not work for your use case. Always keep your components (especially external components) content-agnostic. If they are meant to contain or hold content, build that into the component, but make sure that that content can be provided on a "per instance" basis. This does often fall under the same sort of idea as making sure you are not making everything into a component and making sure you are planning your components, but it deserves its own spot because it can be a very big issue. It may seem obvious to some, but components should never contain page-specific copy, images, or icons. I'd even go as far as to say that any copy you have in a component should, at the very least, be customisable.
Components libraries are great. I love building them and I love using them. However, they are deceptively difficult to do right. I hope this article gives some good insights into how you can build better components libraries for your component, based on what I have learned from my experience. Good luck and happy coding.