We arrived late to the Component Library party, which means we had plenty of time to read all the blog posts on the best ways to create one. The problem with reading about “Best practices” and “Questions to ask before jumping in” is that they guide you down a path that worked for those developers. Without knowing the scale of their project, the size of their team, and the purpose of their library, it’s difficult to know whether their advice is valid for you and your team.
This post is not about advice, it’s not about best practices, and it’s not about selling the idea of why component libraries are the worth investing into. Many more intelligent and better suited people have written great articles about those subjects. This post is a collection of my thoughts on what we did wrong when we went about building ours, called Spicerack.
An introduction, for context
Firstly, a bit of an introduction to our team and what we do. We are four developers—a CTO who strives for perfection regardless of deadline, a front-end developer who would rather ship something stuck together in tape than nothing at all, and two junior developers who are still learning the ropes when it comes to development. Together we make a great balanced team that pushes each other to do great work but knows when to move onto the next phase.
With such a small team, the task of getting everyone on board to start building this library was easy—I said we had to do it, the CTO agreed, and we started.
If we don’t have everything we don’t have anything
We started off by writing up a list of components we thought would be required for future projects. This list was based on the components from Content Management Systems we had developed over the past three years. Each of those components had a list of requirements for what they should do and how they should do it. I then went about designing them in Sketch, along with variations for their different states and usages.
This long list created a problem—we obviously couldn’t start using this library before all the components were ready. And as any developer should know, nothing is ever truly ready when it comes to software projects.
Our CTO had enough and decided to use the components that were “ready enough” in an existing project that needed some updates. The design of the new components didn’t match the existing ones but the client agreed to move forward knowing that maintaining the project would be easier.
The time we invested in the component library was already paying off and we could see how the components were working in a live project. In the end we removed the components that weren’t needed in existing projects from our list and focused on the essential ones. As soon as a component reached the working phase we implemented it in an existing project.
Three different components for a single purpose
Before being able to use the components in an existing project we had made many assumptions on how they will be used, the data that will be passed around, and the purpose of those components. Once we started using the components we realised that some of our assumptions were incorrect.
We had created three separate components that were quite similar. The decision was to develop them as separate components as their uses in previous projects were distinctly different. After using these components in a single project we noticed that, although they were structured differently, they were used in such a similar manner that a single one would suffice.
We merged the three components into a single one and made it flexible enough to handle the use cases required by the project they had been tested in.
We wanted to have a reference point for each component without having to open the library’s code or running the project on our local machine. We solved this by creating a Storybook and uploading it to our server. This worked great as we were able to preview our existing components, see how they worked, and how we should implement them.
Unfortunately, we spent too much time thinking about how to layout the stories and what information was important. The only reason we needed the stories was to show example code and correctly show how the component should render.
Spending time on organising the stories, structuring each one in a hierarchy that made sense, and adding tables took time away from developing the library. This structure also meant that making updates to the entire library resulted in going through each story to standardise them.
Now that we have all these components, how are we going to theme them?
When starting this project, we didn’t think that theming our components would be necessary. We had the discussion early on in the planning stage and decided that since these components will be used for developing client facing products they can all be themed the same.
This worked out well, initially. Setting up a project was simple, just install the library and drop the components where they were needed. Then the time came when we needed to adjust the style of the components. Not only for different projects, but for different usages of a component in a single project.
Each component needed to be updated so that it could be instantiated with a theme. Not wanting to have to setup a theme for each project, or having to install the theme through Spicerack we decided to write up a default theme in the component library. The theme defined the attributes of all components which we felt might need to be overridden. A component could then be instantiated in a project by either using the default theme alone, the default theme with some attributes overridden, or by using an entirely custom theme.
This problem trickled into the previous problem, where we had to update all instances of the components in our stories.
Creating a component library is a tough bit of work and it’s not always needed. It becomes a never-ending project which needs to be maintained and further developed. The end year goal for the library is to have user management, a spreadsheet component, and basic media management.