Create a design system with Lion web components


Like many companies, there is a need of design system for a lot of reasons. At Ubisoft, our internal design system is called Egg and focuses on the productivity tools we make.

For two years we have been making an implementation with web-components using lit-element until I saw this article for a library named Lion, allowing to create a design system on top of it.

Lion web components is a set of highly performant, accessible and flexible Web Components. They provide an unopinionated, white label layer that can be extended to your own layer of components.

We were pleased to update our implementation to use lion.

In this article, we will try to explain the reasons why we have chosen Lion, how it was done and how we benefitted from using Lion as our base.

lion — ing-web — Egg

Extend Lion

Here is a simplified example of the egg button extending @lion/button.

When doing multiple components, you will need a theme mixin to set all the css variables. To make it work without the mixin, I’ve copied the CSS variables values in the default of the variables var(--egg-primary, #1976d2). You don’t need to add the default value: var(--egg-primary).

Theming is easily done with CSS variables since they inherit their value from their parent. Custom themes have been made for dark and light and many different colors without needing to change the components.

JSDoc is used to generate a documentation with web-component-analyzer. You can display it in Storybook or in any documentation website.

Extract of Storybook API for the egg button

Create new components

Lion have a lot of building parts you can use to create what you want. You can check some examples of extension in Lion documentation.

Our progress indicator extend LionProgressIndicator with 3 types of indicators.

Progress indicators

We have created a button bar with LionListBox just by adding some styles.

Button bar

We have proposed a simple menu with Lion OverlayMixin.

Simple menu

Wrap component for React

Since we want our components to be used in different frameworks, we need a wrapper at least for React. You have multiple wrappers doing it, here is an example:

Some teams at Ubisoft were starting to use a Micro-frontend architecture with client-side load faced some were issues with that approach. Custom elements names need to be scoped with something like @open-wc/scoped-elements. Lion already scopes all its internal elements with it.

While wrapping for React, we use the same technique @open-wc/scoped-elements mixin in order to register the custom element with a unique name to be able to use it in a Micro-frontend.

The same wrappers are available for Vue and Angular to make it easier to use it in these frameworks and with custom element scoping for Micro-frontends.


Lion already tests most of the code of its layer. In our layer, there is mostly only css. Visual regression testing is the main part of test we do on our components. Visual tests are made for each components using Storybook for serving files, and Playwright to control and take screenshots.

Open source

One benefit of using Lion was to be able to use and contribute to the Lion project. If some code was waiting for validation in Lion, we just add it in our layer. When it’s released in Lion, we update the library and remove the unnecessary code.


Using Lion Web Components helps us to accelerate our design system implementation since we mostly have only CSS in our layer.

We are very happy to work with the great community around Lion.

Thank you to Mathieu Puech, author of this text.

This article was first shared on the ING blog. You can find it here.