Storybook — Chromatic — Loki
An article co-authored with Jean-François Greffier
Overview of solutions for collaborating around a library of custom components.
Intro
Modern front-end applications are intended to be modular, thanks to an architecture following the principles of Component Oriented Programming (POC). This is a pervasive trend in modern JavaScript frameworks like VueJS, Angular, etc.
Components are particularly interesting when they are reused, either when they are generic components within an application, or on a larger scale in a design system. A design system allows you to create a library of components with a unified design, branding in mind. Some are public, like Material Design or the WordPress design system.
However, there are many challenges to sharing, documenting and above all collaborating around a design system (as Cécile Freyd-Foucault explained well in her conference at Devoxx France 2022 “Petit guide pratique pour commencer un design system”). Fortunately, there are tools to make our task easier: we will see in particular the Storybook — Chromatic couple.
Beyond the desire to do well and to set up a design system because it is considered good practice, there is a big and immediate added value.
More precisely :
- List and share components
- Test
- See again
- Approve or not
- Document
- Maintain
- Embed multiple components in one page
Storybook, the first tool we are going to see, is the basis of the other solutions presented in this article.
Storybook
Storybook is a web application for building libraries of components and pages in isolation. Thousands of teams use it for UI development, testing, and documentation. It is a free and open source solution.
It’s a simple way to share a library of components, or even an entire design system. Storybook also allows you to view and interact with components outside of their usual application ecosystem, and therefore to test them in a neutral context.
Indeed, it can sometimes be tedious to develop a component that must be integrated into an application, because there are many obstacles: the complexity of the application, the development environment, the test environment, the need to connect to a back end. Having isolated components eases the work of verification, manual testing and distribution.
To make the documentation and visualization of the library available in real time, and without developing specific pages, all you have to do is host the application to make a showcase. This is a considerable time saver since there is no longer any need to maintain an additional application.
Stories
Stories are dynamic examples of components. A lively and interactive documentation allowing both to see use cases, but also to visualize the variants of the same component.
All you have to do is add it to your project’s dependencies, import your components and associate a <name>.stories.js file with them, which will contain its possible arguments and links to its template.
For example, with a Story with a VueJS component: a button with several options (primary or secondary type, size, etc.)
File button.vue
<template>
<button type="button" :class="classes" @click="onClick" :style="style">{{ label }}</button>
</template>
<script>
import { reactive, computed } from 'vue';
export default {
name: 'my-button',
props: {
label: {
type: String,
required: true,
},
primary: {
type: Boolean,
default: false,
},
size: {
type: String,
validator: function (value) {
return ['small', 'medium', 'large'].indexOf(value) !== -1;
},
},
backgroundColor: {
type: String,
},
},
emits: ['click'],
setup(props, { emit }) {
props = reactive(props);
return {
classes: computed(() => ({
'storybook-button': true,
'storybook-button--primary': props.primary,
'storybook-button--secondary': !props.primary,
[`storybook-button--${props.size || 'medium'}`]: true,
})),
style: computed(() => ({
backgroundColor: props.backgroundColor,
})),
onClick() {
emit('click');
}
}
},
};
</script>
It is associated with a Button.stories.js
file to make the link with Storybook:
import MyButton from './Button.vue';
// More on default export: https://storybook.js.org/docs/vue/writing-stories/introduction#default-export
export default {
title: 'Example/Button',
component: MyButton,
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
argTypes: {
backgroundColor: { control: 'color' },
onClick: {},
size: {
control: { type: 'select' },
options: ['small', 'medium', 'large'],
},
},
};
// More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args
const Template = (args) => ({
// Components used in your story `template` are defined in the `components` object
components: { MyButton },
// The story's `args` need to be mapped into the template through the `setup()` method
setup() {
return { args };
},
// And then the `args` are bound to your component with `v-bind="args"`
template: '<my-button v-bind="args" />',
});
export const Primary = Template.bind({});
// More on args: https://storybook.js.org/docs/vue/writing-stories/args
Primary.args = {
primary: true,
label: 'Button',
};
export const Secondary = Template.bind({});
Secondary.args = {
label: 'Button',
};
export const Large = Template.bind({});
Large.args = {
size: 'large',
label: 'Button',
};
export const Small = Template.bind({});
Small.args = {
size: 'small',
label: 'Button',
};
And here is the rendering in the Storybook interface:
From there, we can change its arguments (here size and primary/secondary status), change the text content or the locale in order to see how the display reacts, add a dataset via a JSON to simulate a return from APIs, etc.
Addons
Finally, there are many free and useful addons to enrich the functionality of Storybook.
For example, it is possible to build entire pages, then to link stories together using DOM events (typically the click event). Ideal for representing a user pathway, it is possible with the Links addon.
You can also use the Accessibility addon. Very interesting, it allows you to test the possible rendering of a component for people with various visual abilities (fuzziness, several forms of color blindness, gray levels, etc.):
Here is a selection of interesting addons:
- Links
- Accessibility
- Locale i18n, which allows the change of locale by a simple select box
- Design, to have the preview of the UI design from Figma
Tests
While Storybook allows for pretty cool visual testing, it doesn’t replace component unit testing and end-to-end testing.
Tests that can also be integrated into Storybook with addons:
Chromatic
Chromatic is a collaboration platform for hosting Storybook builds, adding feedback to them, and reviewing changes to the component collection.
We can say that it is used to review, in detail, the changes following a new build of a design system. How it works: for each new version, a visual regression test is created, then, with each modification, it is possible to validate or not the changes and to discuss as a team directly in the tool.
As you will have understood, Chromatic is tailor-made and exclusively for Storybook. No wonder, since the same team is behind these two products.
With each modification pushed via Git, a build is created by Chromatic.
This will produce several things: a hosted Storybook, examples for each component, and a list of changes detected by the application.
For each change detected, a screen allowing to visualize the difference, to compare the DOM and especially to use a system of comments and validation.
In addition, we note the possibility of inserting it into a Continuous Integration chain: it integrates with Gitlab, Github actions, Jenkins, etc.
Chromatic is a paid tool, but with a reasonable freemium plan. Indeed, the free version allows several people to collaborate, and to integrate Chromatic into their CI. However, the free version is limited to Chrome snapshots only and 5,000 snapshots per month. Good enough for an in-depth evaluation of the tool or even for a small team.
The premium version starting at $149/month offers more snapshots, a custom domain name and more browsers.
Even the free version allows for multiple projects and teams, which is quite flexible. Note that it is not possible to host Chromatic on a private server.
Loki
Loki is an easy-to-implement, browser-based visual regression testing tool without a graphical interface (headless). Rather than requiring you to have a specific setup or syntax for testing, Loki uses the stories you’ve already created. The tool easily integrates with Storybook and allows you to take advantage of component isolation and all the examples in your component library in order to detect possible regressions.
Loki is a simple tool that, when a Storybook is available, works from the command line. This allows it to be used locally or in Continuous Integration. Just let Loki generate reference images for your stories, and the tool can then use them for its tests.
On the other hand, there is no interface for collaboration, validation or even comparison. It’s minimalist, but effective.
Loki can be an alternative to Chromatic if you’re only interested in the visual regression testing aspect.
Encountered difficulties
During our Proof Of Concept, we encountered difficulties in interfacing Storybook and Loki with a ViteJS stack. Including with the future version Storybook 7. Either the Storybook library did not build in static, or the stories of the VueJS 3 + ViteJS components were not detected by Loki. A more classic configuration based on Webpack was not problematic.
It also has a point of attention common to all visual regression test solutions: reference images. Indeed, these images are created in a specific context which means that the rendering may be slightly different. Operating system, installed fonts, browsers are all parameters that can create differences.
The solution for Loki is to go through a Chrome running in Docker, via the target option. It can be restrictive because you also need Docker in the CI, via a specific runner configuration in GitLab CI for example. No worries for Chromatic since everything is remote.
Conclusion
Beyond the maintainability of a design system or a library of components, the interest of these tools lies in the collaboration:
- Storybook allows you to visualize and interact with a set of components (manually or with tests)
- Chromatic adds a collaboration space to validate, approve, easily exchange around a build
- Loki automates visual non-regression testing to ensure component quality
The implementation of a component library, or a design system, has an immediate added value thanks to these tools which is to ensure quality through documentation and better testability of frontend components in general: no need for a design system to try and take advantage of Storybook or Chromatic.
Finally, the most important thing is not the tools, it is the communication and the self-organization:
“Individuals and interactions over processes and tools” Agile Manifesto
Additional Sources
See more projects using Storybook, go see this showcase.
- “Petit guide pratique pour commencer un design system” by Cécile Freyd-Foucault — FR
- “Stop aux régressions visuelles de vos composants UI, avec Storybook et Loki” by Jérémie Ledentu — FR
- “Developing, Documenting, and Testing your Vite app with Storybook” by Ian VanSchooten
Thanks
I would like to personally thank Abraham Mubanzo for his great meetup regarding Storybook at Conserto, and Jean-François Greffier for trying these tools and writing this article with me as my fellow #explosConserto.