Component Library

At The Bank of London, one of my primary areas of responsibility is our Component Library, a suite of reusable UI components that makes it easy for our teams to build incredible experiences.

The Results

My team and I built this from scratch. Today, it consists of over X components and is used by 7 different applications at the bank across 4 teams. It's become a resource that engineers use on a daily basis and when I interview the teams to get feedback, their main response is "it just works well, I don't have any suggestions for improvement". (FIND A BETTER QUOTE). The library has everything our product teams need to easily build UI that follows our design system. It's got everything from the very basic colors and sizes, to foundational components like buttons, inputs, and forms, all the way up to complex features like our AI chat panel. Our teams can ship UI at a blazing fast pace and focus on the important parts of the user experience, we've got the basic look and feel covered.

How We Built it

Shortly after we our first designer joined the firm, we quickly started redesigning our online banking application and onboarding flow. The designer, tech leads, and I quickly decided that building a design system and component library was going to be critical for the online banking and onboarding teams to quickly ship a cohesive pair of applications.

Since my team had finished up a rewrite of our marketing website and had some new engineers coming on, I picked up the component library. My senior engineer (really my right-hand man) and I decided on the critical parts of the architecture early on. We were going to build this using Radix primitives, Tailwind CSS, and pull in other libraries as needed. This gave us a ton of flexibility in how we wanted to build, without making us reinvent the wheel on CSS, accessibility, or universal functionality.

One of the most critical parts of our architecture is our testing solution. We're using Storybook and Chromatic for our interaction, visual, and accessibility testing. The visual regression testing piece has been key to keeping velocity high as the library has grown. Not only is manually regression testing the look and feel of UI tedious and error-prone; our work is consumed in entirely different projects that we don't know the ins and outs of. This makes it practically impossible for us to check every place our components get used (our primary button is referenced over 400 times as of writing this!). Being able to capture snapshots of all our different variants across browsers and use cases and rely on those as we iterate is what lets us reliably deliver for our product teams.

How the Project Evolved

Our approach to the developer experience changed over time. When we started, we knew we had to balance making it easy to get great looking UI with giving devs the flexibility they need to get the job done. Initially, we started out with a very flexible API that let consumers inject styles and UI all over the place. But, I quickly realized how fragile this made things. We couldn't make some critical changes without doing in-depth analysis on how devs were consuming our components. Many changes ended up being breaking changes when they shouldn't have been. Ultimately, I worked with the designers to tighten up the designs around a very standardized set of components, which eliminated the need for all the customizability we had added in. This left us with a clean API that was easy for our consumers to understand and use. It also made evolving the designs much simpler.

The way we built components as a company also changed over time. When we first started the Component Library, nearly all of the product shop was aligned around a massive upgrade to our online banking app and onboarding flow. There was a very regimented process around requirements, design, development, and shipping to clients.

My part of this process was making sure that the components landed in the library before the product squads needed them for their work. I had to balance giving my team enough time to build high quality components with giving the designers enough time to build stable designs. If I waited around for the truly final designs to come out, my team would be crunched for time to ship the component. If I gave my team the work too early, there could be massive changes to the designs that waste their time. I was able to strike the right balance between these two by adapting my approach based on the component. For simple components like buttons and inputs, I'd make sure there was enough room on our schedule to get the work done and stay in sync with the designers and product teams to keep things running smoothly. For more complex components like charts and drag-and-drops, I'd get the designers and product teams to nail down behaviors early on. Then, I'd have my team architect and PoC a bare-bones solution before we got the designs. This let us get the hard work done ahead of time.

Once we got past the updates to our online banking app and onboarding process, the demand for new components dropped substantially and the process where work flowed from designers to my team and finally to product teams started to get in the way. Especially for minor changes like bug fixes or adding a new variant to a component. So, I adapted the process and empowered the developers on the product teams to make changes to the Component Library themselves. These days, the library is a community effort, with most PRs coming from outside my team. We still handle the most complex or foundational work, but removing ourselves from the critical path was key to the mission of helping other teams ship faster.