Driving consistency across Druva UIs: Building a common component library – Part 1

Prashant Monteiro

Druva has multiple applications to support various products that use a combination of different technologies that have evolved in the UI space over the years. One application uses plain JS/HTML, another uses JS/Jquery and of late, React is the framework of choice. As a result, similar UI components were built across products as and when required, using technology that was the flavour of the moment, leading to differences in the look and feel and behaviour of the applications.

As Druva and our products matured and customers started using multiple products from the Druva suite, we decided to standardize and enhance the user experience across products. While this could be done by providing a standard set of guidelines and CSS, it meant that each product had to implement them individually. There was no consistent way to uniformly change styles across all the products since each product has its own implementation. With newer products and features being introduced, developers needed to build everything from the ground up in order to conform to the standardization guidelines, slowing down the development process.

The solution was to provide a common component library, which could be used across all products. By definition: “A user interface component library provides a set of building blocks, that can be used to build a user interface quickly.” Examples of such building blocks are tables, buttons, input elements, header bars, side bars, and so on.

Identifying the commonly used components

The User Experience team conducted a study to identify the most commonly used components across all the products. Meanwhile, the UI engineering team focused on using ReactJS as the framework of choice across all products.

To get the component library up and running quickly, we decided to leverage the existing component libraries as the foundation. The libraries shortlisted were:

Bootstrap was already well established and Semantic UI was relatively new. Semantic UI was interesting and we did evaluate it, but eventually decided to use Bootstrap because:

– Bootstrap had a larger user base compared to Semantic UI

– Semantic UI being new, we were not sure of support for it in the long run. (This proved right, because Semantic UI is not maintained now. Alternative to it is Fomantic UI )

– Engineers were already familiar with Bootstrap.

– Bootstrap 4 was already being used across multiple products, so migrating to a new framework was not feasible due to time and release constraints.

Once the UX team decided to use Bootstrap as the foundation for our design system, we narrowed down on Reactstrap and React Bootstrap. At that time, Reactstrap already supported Bootstrap 4 and provided a majority of the components that we required, so we finalised on ReactStrap as our base library.

Keeping it simple..

  • We used create-react-library to start the library development. This uses Rollup for bundling and provides boilerplate code to quickly create React libraries.
  • Our components are simple wrapper components over the Reactstrap components to restrict behaviour and add styles as required by the UX specifications.
  • We used plain SCSS styles to apply custom styles to the components. While there were (and still are) differing opinions on whether to use styled components, CSS-in-JS or CSS Modules, we decided to start with simple CSS. Since our plan was to keep our components look and feel as close to Bootstrap, we did not feel the need to add an additional library for styled components. While researching we also found that Styled Components tend to increase page load time and asset size due to inline CSS being used, though we did not test this.
  • Since we use global CSS, the classes shipped with the component library have a special prefix to avoid clashes with product-defined classes.
  • We decided to follow git flow for our development and release process.
  • In order to reduce the JS footprint, we implemented support for tree shaking within the library and minify and obfuscate the library before releasing it. The library size reduced from 2.3MB to around 1.6MB, but the real benefit to products was due to tree-shaking. Their JS size reduces depending on the components that they use from the library.

Adding new components

The demand for newer components increased for the products. To support these demands, we added newer libraries like react-virtualizedreact-select, and react-datepicker using the same principles described above.

Fig 1: Few UI components

Few UI components

Establishing a common component library

Our requirements drove us towards adding visual components (tables, buttons, tooltips), operational components (modal, popover, wizards), navigational components (tabs, header bar, side navigation) and more, that would be commonly used as well as drive consistency across all products. In our next blog we will cover how we incorporate the new common component library into development processes.

Related reading:

  • How the front-end architecture at Druva has not only helped create a fast and responsive UI, but also helped in adopting modern design principles, covered in this blog Say Hello, A Refresh to Your Druva UI Experience Part 1 and Part 2
  • Learn more about how the common component design impacts the end-user experience as part of the new UI for legal hold