Beyond Bootstrap
Moving from UI toolkit to component library
The first factory predates the industrial revolution by hundreds of years. Veniceβs Arsenal pioneered assembling naval ships out of standardized parts. Engineers of the time discovered that it was quicker and easier to assemble complex things from their constituent parts rather than build them from scratch. Today, weβre seeing this idea of prefabrication and assembly take hold in a different sphere of engineering: building user interfaces.
User interfaces are increasingly assembled from standardized parts. UI toolkits like Bootstrap were among the first to provide a generic collection of parts for web UIs. These toolkits enabled developers to easily find and apply patterns in their apps.
Companies too recognized the value of having their own UI toolkit. They created living styleguides to match the look and feel of their brands. However, building a styleguide requires significant resources so only larger teams tended to invest in them.
A key change in the industry has come with the advent of UI componentsβββbuilding blocks of user interface akin to Legos. Components simplify building custom UI toolkits because they encapsulate design patterns in modular standardized units.
This paradigm shift allows teams of any size to create βcomponent librariesβ tailored to their exact needs and brand. Today, Iβll walk through how we got here and the process of creating your own component library.
User interface assembly
Frontend developers build the same user interfaces over and over. There arenβt many functional differences between them. Youβll usually find the standard combination of header
, sidebar
, lists
, and forms
.
Throughout history people have found that itβs more productive if people assemble new products from existing parts. User interface engineering is no exception. Composing new views out of existing UI parts is faster than building them from the ground up.
At first these patterns took the form of ad hoc code snippets. They lived in text files stashed somewhere on developersβ machines (pre-Github). Albeit not very shareable, these bits of UI code had enormous utility to the frontend developer.
Bootstrap and UIΒ toolkits
Bootstrap came along and consolidated these pieces of UI code into a single well-documented collection. The key idea of UI toolkits was to provide an inventory of generic/universal design patterns (with accompanying code).
At the time, the workflow was revolutionary in its simplicity. You copyβpasted markup and got workable user interfaces. UI toolkits made it trivial to scaffold simple sites and line-of-business apps.
The concept of UI toolkits had an enormous impact on design and development. It proved that designers could ensure user interface consistency throughout the development process. It also highlighted how easy it could be to create UIs using a toolkit to developers.
Living styleguides
Living styleguides are organization-specific UI toolkits. Teams saw the inherent value in UI toolkits, but often had specific look and feel requirements. They couldnβt just adopt Bootstrap, Foundation, or Semantic.
The classic downside of something like Bootstrap is that you must adhere to its prescribed idioms and styles. Sites that rely on popular toolkits tend to look the same. You can probably see why this isnβt ideal for a company looking to stand out in the market.
Like Bootstrap, living styleguides provided a similar inventory of design patterns along with code, but these patterns reflected the particulars of company branding and design.
At the scale of Yelp, Walmart or the US government, reusing existing design patterns yielded massive efficiency gains. Living styleguides made it easy for big companies to create a consistent look and feel across their web properties.
However, creating a living styleguide is a significant undertakingβββoften requiring coordination from the top down. There are countless UI permutations to design, build, and maintain accompanied by the daunting task of getting buy-in from everyone on the team. Realistically, the luxury of living styleguides was reserved only for large teams.
Component libraries
Component libraries are a pragmatic way for teams βlarge and smallβ to get the ease of Bootstrap, the customizability of living styleguides, and the flexibility of modern view layer technology.
The widespread adoption of view layers like React, Angular, and Vue compel teams to decompose UIs into simple components. These components serve as the building blocks of apps; the collection of components is the basis of a component library.
Components: self-contained functionality
As a construct, components are more powerful and easier to use abstractions than raw code. They are self-contained pieces of functionality that have well-defined inputs and outputs.
Self-containment encourages developers to scope functionality, markup, and styling(this area is rapidly evolving) at the component-level. No need to rely on toolkit-level JavaScript or stylesheets, with UI components all of this can be encapsulated in the component.
Small teams can build component libraries
The focus on components βthe user interface equivalent to Legosβ makes it easy for small teams and individuals to start building their own inventory of custom design patterns piecemeal. Since you progressively accumulate UI components, the startup cost of a component library turns out to be less than building a living styleguide (which often requires much forethought and planning).
In addition, flexibility is inherent to component libraries. Each component can be added, updated, or replaced without affecting the integrity of the library. This means that youβre not constrained to one UI toolkit at a time, you can mix, match, and customize components from around the web as needed.
How do I getΒ started?
Whether you have an existing app with components or are building one anew, starting to accrue the benefits of a component library is easy. Since youβre able to add components individually and the tools to build libraries tend to be development-only by default, the cost to try a component library is close to nil. Letβs see how to get started in 4-steps.
1. Get a place to βstoreβ your components. Components are often buried inside apps. This isnβt ideal because people have to scour through directories and screens to see components in action. What you want is a central place to catalog and visualize your components. You can find these library-like features in a component explorer.
Component explorers
- React: Storybook, Cosmos, Carte Blanche, Styleguidist
- Angular: UI Storybook, Playground
- Vue: Vue play
- Ember: Freestyle
- Clojure: Devcards
2. Index existing components. Once you get a component explorer, itβs time to index your appβs existing components so they can be found.
Start by importing the component explorer tool at the top of your component file (the exact syntax varies between component explorersβββIβm simplifying for readability).
import { specsOf } from β@component-explorer/explorerβ;
Next, write your first βtestβ states for that component as specs
. For instance a Toggle
component might have default
and active
state.
specsOf(βToggleβ)
.add(βdefaultβ, () => <Toggle active={false} />)
.add(βactiveβ, () => <Toggle active={true} />)
Then checkout the component in action via the component explorer. Repeat this process to index other components and grow your library.
3. Browse thousands of open source components. There are plenty of readymade UI components available from organizations like Salesforce, AirbnbEng, and Google. Familiar UI toolkits like Bootstrap and Foundation have also been converted to UI components. For complex components like graphs
, I suggest browsing what is already available before building something from scratch.
4. Add open source components to your library. Once youβve found something you like, itβs time to put it in the component explorer (as we did in step 2). This gives you an isolated playground to tweak the readymade component before integrating it into your app.
Letβs simulate the process of adding an example LineGraph
component to the library.
Installing via NPM: npm install linegraph
Create a new file to import
the component, the component explorer, and record the test states as specs
.
import { specsOf } from β@component-explorer/explorerβ;
import LineGraph from 'linegraph';
Add a few test states to adjust the look and feel in isolation with your component explorer. Hereβs how the component would look with a default
and active
state:
specsOf('LineGraph')
.add('Default', () =>
<LineGraph data={latencies.map(latency => ({
latency,
count: 5000 + Math.random() * 15000,
}))} />)
.add('Active', () =>
<LineGraph active={true} data={latencies.map(latency => ({
latency,
count: 5000 + Math.random() * 15000,
}))} />)
Once youβve adjusted the specs
to match your needs, itβs simple to add the component wherever you need it in your app and use similar specs to achieve the intended appearance.
Beyond Bootstrap
Bootstrap pioneered the use of readymade user interfaces. People could pull interface elements off the shelf to rapidly build UIs. However, it required adherence to prescribed idioms and styles.
Living styleguides allowed organizations to offer the same rapid development experience as Bootstrap with a custom look and feel. The challenge was that these styleguides required significant effort.
A component library is a practical middle ground that enables rapid development and customization without needing much in the form of organizational momentum. Here at Chroma, we are big proponents of component libraries because they tend to guide teams into reuse and UI consistency without being authoritarian about it.
Learn more about UI components:
Why you should build UI components in isolationΒ Β»
5-step guide to creating modular frontendsΒ Β»