For any startup building your first UI application from scratch, there are so many decisions to be made. How do you start? What UI framework do you pick? Do you use an open source style and component library or build your own? As the product matures and iterates, these decisions have to be reviewed and what made sense 3 months, 6 months or a year ago may not be the case anymore. This is a recap of our journey so far with our frontend application, how we made the decision to move from a common UI component library to building our own, and some of the considerations to be made when building your own component library.
When Userled first began building our frontend application 2 months ago, our focus was on delivering as quickly as possible to prove the value our product could bring to our users. To help us do this, we wanted to utilise as many open source libraries as possible and avoid building everything from scratch. We decided to use NextJS to give us the option of server side rendered pages while still building on top of React - one of the most popular frameworks out there with plenty of documentation, a well established community and an extensive library of supporting packages.
When it came to the decision of what style library to use, there is overwhelming number of options out there such Material UI, React Bootstrap, Headless UI etc. As with many decisions at an early stage start up, our choice largely boiled down to what we had the most experience in, allowing us to move quickly with minimal up-skill time. The first iteration of our frontend application brought in tailwind CSS and tailwind UI components. Choosing an established open source style and component library is great when starting out. It meant we had components out of the box which were nicely styled, could be customised with minimal effort and managed many UI concerns for us.
As we delivered the alpha and beta versions of our product, we began to prove the value of our product to our users. As we did so, the need to build a strong brand around our product became more and more important. This meant establishing clear brand guidelines with consistent tone of voice and styling across all our applications. Read more about how we define Userled’s tone of voice here.
As we customised our components more and more to follow our style guide, we found we were overriding so many styles and behaviours that it was starting to make sense to create our own library of reusable components. We still build all our components using tailwind CSS and in some cases on top of Headless UI components. However we try to wrap all of this behaviour in a generic common Userled component that can be shared across our frontend and ensures a consistent look and feel across our app. Although there’s an overhead with creating and maintaining a component library, we strongly believe this will help us deliver faster in the long run as our component library becomes more feature rich and forms the building blocks of our UI design.
The first step to creating a useful component library is to ensure styling is consistent across your application. There’s no point building a shared component library if you have to customise it with every usage. This is achieved by having a well defined design system of composable components that are used as the building blocks of every design.
Create a theme for your component library that encapsulates your brand and style guidelines. This should include colour palettes, typography, spacing, and other design elements. This ensures consistency between components and helps with rebranding or creating sub-branding in the future - you’ll be able to customise your components by tweaking your theme rather than having to make changes across all your components.
Ok so you’ve got a design system and common theme set up, now what? Building a component library is a big task and not something you’ll be able to achieve in one go. Start off small and don’t worry about building all your components in one go. Focus on components that are highly reused across your application and have lots of common behaviour. For Userled, we started with buttons, text inputs and select menus. Keep in mind the reuse, modularity and extensibility of each component. For example you want to create a copy to clipboard icon button. Instead of creating this component straight away, consider creating an icon button component first that takes an icon and an onClick handler. The copy to clipboard icon button can then be built using the generic icon button where the icon is the clipboard icon and the onClick handler copies some text input property to the clipboard.
One of the major benefits of having a common component library is that it helps address common UI concerns out of the box. One of these is accessibility. When building a component library from scratch, it’s much easier to implement your component in an accessible way from the get go rather than having to make a breaking change later to accommodate this. For example an SVG button cannot be clearly described by a screen reader. Instead every icon only button should have an aria-label which describes the button. A component library can enforce this with a required label property on the icon button component. Adding this required property after the component has already been adopted would break all usages of the component. Other common accessibility concerns that can be addressed by component libraries are focus and hover states on all interactive elements, handling keyboard navigation and ensuring sufficient colour contrast on components.