November 2, 2021

How web components took our design system to the next level

After several years of working as a frontend engineer and design manager, I have personally learned many of the challenges of working with an existing codebase. Over the years developers have introduced one or more third-party UI libraries to help speed up the development of features in a product. As you know, people come and ago and new team members may prefer different tools. Once a library is introduced to the development stack, it will be part of the codebase for many years to come, adding to the number of libraries the team has to learn to work with the product.

Over the years, I have worked with several versions of Bootstrap, jQuery UI, Angular Material for AngularJS and Angular, as well as custom components following the Atomic CSS pattern by Brad Frost. While these tools have been great in developing scaleable UI components as part of a design system, many of them run into compatibility problems. For example, we started one application with AngularJS and used the Angular Material library for that version. When the new Angular version was released, our team decided to build new applications and features with it moving forward. It left us in the position many mature products are in, with different technologies as part of the tech stack that are not compatible with each other.

As the design manager, our team struggled to implement a consistent experience for different areas of the product. Common components like checkboxes, buttons and inputs did not look or behave the same. Features were built using old UI libraries that were no longer being maintained. Modern libraries like Angular Material cannot be used without rewriting a product feature. There were other libraries to help with that problem, but that also meant another library to add to the already melting pot of third-party libraries the team was already using.

To solve the problem, I took on as a side project, the development of a UI library built with web components using Stencil JS. At the time, I could not get buy-in from management to dedicate engineering resources because the priority was on other crucial features. It took me about six months to build a good base for the library. I developed the most commonly used components across our stack. Many mistakes were made, but the results were gold.

After a few months we were able to reuse these components in the legacy areas of the product without the Angular framework, as well as the areas developed with both versions of Angular. Today, we are slowly removing the need for 3rd party libraries. We have been able to leave existing libraries alone to minimize the impact. The components were developed with a similar interface to those of Angular Material. This approach has allowed us to easily swap the components when we do touch an existing feature. One-by-one, we have been able to reduce the need for 3rd party UI libraries. While our teams still rely on them in some cases, the benefits of having a component library that works with or without any modern frontend framework is clearly showing for our team. Designers are able to design consistently across the product without having to worry about an increase in development scope due to the UI design.

The components were published as a private NPM package. This approached allowed different apps to work with the different versions of the library, allow my team to continue to develop the library with minimal effect on existing projects. Building with web components also helped us document the components as part of the design system. Developers and designers could visit the documentation website and see real examples of the components, as well have code snippets to quickly get started.

The final result has been a win both for engineers and designers. It’s the one UI library to rule them all. Web components can also work well with Progressive Web Applications(PWA) and hybrid applications for developing native apps. Stencil JS is the core technology behind the Ionic framework and built by the Ionic team.

Let me know what you think, how did you solve this problem?