Our Wave design library in Figma: how does it work?
And how to give it a try yourself
A few months ago, I wrote about how we at FREE NOW created our new Wave design library in Figma. Now it’s time to share more details about its design and operation.
How we set up the FREE NOW Wave Component Library in Figma
Taking a design library to the next level with Figma & tokens
Now you can take a look at it yourself — we’re publishing it in Figma Community.
Wave library core
Wave is a complete design system. In addition to the Figma design library, we have:
- OpenSource code library in the GitHub repository.
- Live demo site, with general documentation and examples of all components and essentials.
At FREE NOW, we use Wave for all web tools. In addition, we have two other design systems for our main mobile products:
- Passenger App.
- Driver App.
All three design systems are based on the FREE NOW brand:
- brand colour palette
- content style guide guidelines
For icons and illustrations, we use dedicated Figma libraries.
Figma Wave library structure
Our Wave library in Figma has a fairly simple structure. Everything except icons and illustrations is in one file. Some people prefer to split the library into separate files, but we decided not to do this for now.
In the file, we use separate pages for:
- Releases — a log of library updates. We use Semantic Versioning to indicate changes
- ReadMe and HowTo — a page with basic instructions for working with the library
- Essentials — brief documentation on the Essentials of the library
- Patterns — documentation on the main basic patterns. We started this section of documentation quite recently. So far, it only describes the basics of buttons
Then there are pages for components, divided into groups:
- Documentation components
Some components from the Documentation components are local and are not used outside the Figma Wave library.
Plenty of design systems use semantic styles in one way or another. In most cases, this only applies to typography: we set levels for headlines, main text, and, if necessary, additional styles (for buttons, for example). And, usually, no one needs to explain what the “Headline1” or “Body Style” is for.
With colours, for some reason, the situation is different. In many open design systems, colours are set either by abstract names (like “$BrandNatural100”) or by HUE level (like “$Red-100”). However, this naming system is understandable only to its creators or requires a constant reminder on their part.
In Wave, we set styles to serve the purpose of use.
Such logic is clear to designers and developers alike, even for beginners. This approach allows you to also simplify the setup for things like Dark Mode:
But most importantly, we no longer have to guess what colour to use. For example, if we need a colour for text — we just select the text style.
Tokens are the basis of our library. All styles (text, colour, and shadows) are based on tokens. In addition, we use several other tokens, which are not directly supported in Figma, like spacings. We use a special component to manage them.
Since Figma does not (at the moment) support tokens natively, we use the Figma Tokens plugin to manage them. In addition, for everything to work as desired, some important things should be taken into account.
Figma Community plugin - Gives you the ability to use Design Tokens that can be used for a whole range of designs…
All styles are created and edited exclusively through the plugin. Otherwise, when you update the tokens, the edited styles will be overwritten, and the new styles will not be bound to the tokens and will be ignored when synchronising with the code.
We use JSON as the data source. The plugin supports JSON stored in the GitHub repository, but we’re still syncing the code manually (copy/paste) through the JSON section in the plugin. Mostly because we haven’t fully migrated all the components in the code to tokens yet, and we’re still working on a solution to automate synchronisation and updates.
In the documentation on the “ReadMe and HowTo” page, we have detailed instructions on how to edit the tokens.
We use three levels of abstraction:
Primitive values in a design language are represented by context-agnostic names. We use them to store the brand colour palette and set spacing and shadow parameter values.
Common tokens relate to a specific context or abstraction. They are setting the main semantic mapping. Common tokens help communicate the intended purpose of a token and are effective when a value with a single intent will appear in multiple places (like “colour-action”).
These are the main working tokens we use. For example, for colours, we do not use Base tokens. Only their abstractions in Common tokens.
Component tokens relate to a specific component using them. Their scope only targets the component they belong to. Component tokens communicate not only the targeted properties but also their states.
Common tokens and Component tokens are just aliases to Base tokens: if you change the base values, all the tokens that depend on them will automatically change as well.
For the tokens to work as intended, not only in the design library but also in the code, we need a clear naming convention, which we put together with help from the developers.
The name includes several levels to be descriptive enough. It looks a little complicated at first glance, but in reality, everything is made to make the job as easy as possible for both the designer and the developers.
Mapping to Figma styles
Tokens are explicitly visible only to those designers who directly maintain the design system. The others work with the usual native Figma styles that we generate with the Figma Tokens plugin.
One of the key advantages of using tokens in the design system is the ease of updating the library in case of a change in the colour library (or even a complete rebranding). In our case, the need to be prepared for possible changes in brand colours was the main argument when talking to the developers about switching to tokens. After all, our company has already changed its brand colours. In the past, we had to manually change not only every single component but every single screen. And I’m not even talking about the design. Imagine the amount of work for the developers.
Now all the colours in our design system have a semantic meaning: background, text, icon, and others. Abstracting from the specific values of the colours.
In the case of rebranding, we only need to change the values of the brand colour tokens (or the entire palette) and redefine Common tokens and Component tokens. Consequently, all components, layouts, and even real products get updated automatically.
Fortunately, you can easily adapt the colour scheme in Wave according to your brand if you decide to try it out.
In Wave, we have (as of now) 50 components. This is not a lot, which makes it easier to remember. All component variations are provided by 3,300 variants (in total).
Almost all components are created according to the same principle: core functionality is implemented in the base component, and variations are implemented through variants. Some people prefer to make each variant an independent component to reduce the number of layers or nested components…. but trust me, this approach can turn your work into a real nightmare if you have to maintain complex sets of components.
Of course, we don’t go to extremes with the basic components: if a component has very different sizes and layouts for different variants, it sometimes makes sense to make several basic components to make it easier to change parameters later and be more flexible.
To make it easier to understand which variant does what, we use simple labelling markers on the left and top of the table of variants. This is a fairly common approach that has proven itself useful.
We use a special template for all components, which allows us to stay consistent across the library and simplify our work. In the header of the template, we have a date of the last update of the component (or documentation) and links to live-demo components (where you can interact with them in real life) and code (which can be useful if you want to take a closer look at the implementation).
The template also serves as a basic frame for documentation, for both designers and developers. For design, it is very handy because in Figma you can right-click on the component and select “Go to main component”, and you’ll find the documentation. For example, to understand what options are needed for what use and how to apply them.
That’s where we also prepare documentation for developers who will implement the component. It’s convenient when everything is in one place, especially when several designers work on one component.
Everyone should be able to contribute to the design system. But sometimes, designers just do not know where to start. Often the main question is, “should we create a component or not?”
Together with developers, we have defined a simple decision-making scheme that allows us to understand how to proceed in one case or another.
To make the process even more friendly, we have created a special sandbox library, where each designer can add any Figma component for their projects.
First of all, it will allow everyone to gradually have the opportunity to contribute. For example, a designer might have an idea for a new component but is not sure whether anyone else needs it.
Secondly, the sandbox can be used to decide which components we need to add to the core library and create the right variant in the code.
When we need to add a new component to the Wave library, we start a new branch to create it. It’s best to avoid editing the library directly unless it concerns minor edits in the documentation. But even then, we use the Figma versioning system.
Working in the branch allows you to work without fear of messing something up. After all, the library is used in a lot of projects, and a small mistake can affect plenty of layouts.
That being said, we have a little unspoken rule: a branch should not be open for more than two weeks. This time is quite enough to build a component and even to prepare the basic documentation. No matter how ideal the merging algorithm is, if several people work on the library simultaneously and one branch is open for a couple of months, you might face big merge conflicts. I use long-lived branches exclusively for experiments, which I never plan to merge with the “Main”.
And of course, when everything is ready, it is time for reviewing, by inviting other designers to the branch. They can take a look at everything, ask questions and suggest changes if necessary.
This scheme has proven itself purposeful for development, has become a de facto standard and is reasonably easy to follow when working with such complex systems as design libraries. After all, once components are published, other designers will start using them. And the more time passes and the more layouts/projects will use these components, the harder it will be to make serious changes to them. If you introduce a “breaking change”, it might destroy many design layouts — and make many designers unhappy.
After all the things listed above, keeping release notes may feel unimportant. But it’s important and incredibly useful:
- Release notes allow you to see when and what changes were made. If something is broken and we notice that too late, we can use the change description to track the date and roll back the changes if needed.
- We reuse release notes also in the description of updates of the library in Figma. And according to this description, the designer can decide whether to update or not.
A design system is a product that is never finished. There is still a lot to improve. We are still working on the migration of all components in code to tokens. Also, we understood that we needed a solution that would automate the migration for specific products that we created based on Wave.
We’ve made our system open because we’re interested in your opinions. Please share with us if you have feedback, ideas and suggestions for improvement.
Thanks for reading. I hope you’ve found some useful tips here that you can put into practice.
Working on design systems is incredibly interesting, and Figma is probably the best for it.
Let’s stay in touch! Connect with me on LinkedIn and follow me on Dribbble and here on Medium for more design-related content.