Product Manager: “What is the progress with the new Privacy menu?”
iOS engineer: “We need to sync with the designer to refine margins: 16 or 24px.”
Android engineer: “We use 12dp defaults.”
—Design System joins the chat —
Every article on the Design System (DS) topic starts with its own definition of DS and why it is needed. Let’s try to formulate a simple one:
DS is a set of tools and processes that enables non-designers to create a consistent UI that aligns with the product’s style.
It describes two efforts to create a DS at Flo and their outcomes. We are sharing our findings, tools, and plans so you can save time while starting your own design system. Other articles on the same subject often contain either information about structuring design tokens or instructions for building DS pipelines. Here, we tried to paint the whole picture and show our DS workflow end-to-end with real, simple examples.
It is more about the DS foundations — design tokens — but there are also examples of some components.
DS introduces a set of standards to manage design at scale by reducing repetitive work. Designers can leverage shared language to achieve visual consistency for their product, regardless of the platform (mobile, web, desktop) and channel (email, ad).
Developers always strive for minimum waste and appreciate the following perks of having a DS:
They believe that fewer designers and developers are needed to deliver the same value. There are even some ROI calculators for DS; we hope they are built on accurate data.
There’s an elephant in the room, yet we continue with business as usual. Why?
Employees: “Like any set of standards, a DS restricts our ideas and imagination to an extent. Even if we decide to build a DS — it is a huge task, and it is hard to define first tangible steps and deliveries.”
Business: “DS needs investment, especially from the start. You need buy-in from stakeholders and c-level, show them expected ROI, describe pain points and problems for scaling.”
Therefore, you need to start with forming a group of enthusiasts who can persuade stakeholders, show DS value in small but substantial steps, and break barriers between designers and developers.
For this article, we did some archeological exercises: we installed the first Flo app versions on a real device, unarchived old documentation, and interviewed day-one employees. Here is how it started.
And below are the same app screens eight years later, after the design language was refined through thousands of experiments and user research sessions.
Like any startup, Flo had no formal DS from the start. The earliest documented evidence of design tokens and components dates back to late 2018. It was the 4th year in business: after a couple of closed investment rounds, we doubled our design organization (hired the second designer!), and the brand became recognizable. When all these conditions were met, we naturally started building the 1st design system to keep the development pace and break silos inside the organization.
This is how Flo DS v1.0 first looked like in a nutshell:
This move added more clarity and allowed us to scale our teams, but it had its drawbacks.
There was no synchronization between Figma and code — only manual updates by chance. Some automation appeared later in the form of Figma export scripts for particular modules, but it was still disorganized. Manual support of the source in two places (Figma and Confluence) resulted in missing updates.
Constant ‘small’ overrides here and there (both in design and code) were breeding new undocumented styles each time; later we found hundreds of such cases in code.
And finally, the main pain point was the absence of dedicated designers and developers to support and evolve the DS. Everyone was busy with new features and experiments, a natural state for any startup.
The next significant transformation occurred in 2021–2022, following a new investment round and driven by the need to accelerate growth and value delivery.
This time, the main idea was to push design token changes from Figma to any platform with minimal manual effort and without developers’ help.
This time, after reviewing our first design system, we came up with the following improvements and agreements:
While changes were made in Figma first, we needed to export them into some token storage that supports versioning before conversion to platform-specific formats. The aim was to reduce vendor lock: not so long ago, Sketch and InVision were at their zenith, and then Figma replaced them — we need to be ready for such a scenario.
Another approach involves designers editing tokens in JSON format and creating pull requests in Git. Changes from Git need to be made manually or through API in Figma. Lukas Oppermann recommends this approach in his article and explains its benefits.
We decided to go with the “Figma first” approach because we love our designers 🙂, so they keep working in Figma and only review pull requests.
“Figma first” implies having a structured and convenient set of Figma files and libraries. So we sat with client devs and designers to find out each other’s workflows and pains and establish new practices that fit both parties. As a result, we re-organized our libraries and got 3 main files:
Let’s quickly dive into their content — so that you have an overview of what we’re going to export to code afterward.
Because our design team consists of illustrators and product designers, we agreed to create a Core Colors palette that both teams can use. Illustrations need way more colors than our app UI, but a common color library definitely contributes to overall consistency.
We took inspiration from the Material Design color system, but at the same time, we tried to have fewer tints for each color because too many options can harm productivity.
Then, we created a separate Figma file for all styles and named it Product Tokens. It contains local styles arranged into a reusable library and their visual application on the canvas for better readability.
Naming and organizing these tokens was a tough process, and after multiple iterations, we came up with a hybrid of semantic and component-based approaches. Some examples of our tokens:
color.button.accent
color.banner.success
typography.body.semibold
effect.shadow.level-2
The concrete value of each token is picked depending on the device type, system theme, screen size, and so on.
Each color token in our system has two values — for the Light and Dark mode respectively. Color values are taken from the Core Colors file. We had to create a special script which validates that token values correspond to the core palette (Figma variables weren’t a thing at that time). Here is a visual example of color tokens on Figma canvas.
And the same information but in the Properties panel, displaying local styles and their hierarchy.
Organizing typography tokens was not rocket science: We picked separate fonts for each mobile platform, SF Pro for iOS and Roboto for Android, and derived a set of 14 styles for different use cases.
But hold on, it wasn’t actually so simple as it seemed at the beginning. It turned out that line height in Figma and on Android/iOS devices was calculated and rendered differently. To tweak all parameters, we added real typography samples into our app’s debug menu. This menu helped to make sure that all typography styles looked as expected and matched the source design.
We also experimented with adding our custom font for both platforms, but this story deserves a separate article. In a few words, it is technically doable but requires huge investments and business reasons.
There are hundreds of icons in the Flo app, their number is constantly growing as we are adding symptoms, modes, surveys, and whatnot.
Therefore, all icons need to be categorized and standardized.
We agreed on a name convention for icons:
{size}_{name} / {shape}
Some examples of icon names:
medium_star / stroke
large_event_mood_sad / color
The following set of icon sizes seemed enough for us.
For each size we defined types: circle, square, horizontal, vertical. The shape marker is used to group icons and differentiate them by the style of drawing.
Here is an example of a reusable icon component in the Figma file.
We will not describe all other tokens as they do not change that much and represent just named numbers like screen size, borders, etc.
You cannot build interfaces only on tokens (particles); with time, you start using components (atoms) and nested components (molecules, organisms, etc.) to save effort.
In this article, we focus on exporting only design tokens, but we will also include an example of a button component exported to different platforms.
We made our Figma files look good and organized all styles and components, so what options did we have for exporting design tokens from Figma to code?
After reading DS-related articles, attending
As you can see, we were choosing between external DS platforms and building our own DS pipeline on top of
Establishing design tokens requires significant upfront investment. However, once implemented, they require minimal, infrequent maintenance. This might suggest that specialized tooling for design token management is unnecessary.
After comparing costs and benefits, we chose to build a pipeline on top of Style Dictionary, bearing in mind that later on we could easily adopt a Figma plugin or an external DS platform because all these tools are compatible with Style Dictionary and
The core concept is defining design tokens in a single source of truth (usually JSON or YAML file) and then transforming them into formats that different platforms can consume. You can define any token structure or use the following proposed
Style Dictionary also supports aliases — references to other tokens, allowing you to create relationships and reuse values, which increases flexibility and adds semantics:
{
"size": {
"font": {
"small": { "value": "12px" },
"medium": { "value": "16px" },
"large": { "value": "24px" },
"base": {
"value": "{size.font.medium.value}",
"comment": "Default value if not set"
}
}
}
}
In the example above, there are:
The build system transforms these tokens into platform-specific formats according to built-in or custom rules. Transforms can modify a token’s name, value, or attributes — enabling each platform to use the design token in different ways. A simple example is changing pixel values to point values for iOS and dp or sp for Android.
In a nutshell, our task was to get styles from Figma through API, save these styles as tokens in the Style Dictionary repository, and define token transformation rules for each platform.
Here is a DS automation we came up with after agreeing on all formats: styles are fetched from Figma, saved into Git repository as tokens, then another pipeline generates platform-specific variables, and finally tokens are published to S3 storage to style our
We also set up automatic notifications to DS Slack channel on each stage, so that we can timely respond to issues or important updates.
And finally all changes need to be reviewed in an automatically created pull-request by the design and dev team. We agreed to use the YAML format for tokens instead of JSON because of its better readability and compactness.
But wait, who and how starts the whole DS export process? Making designers go to Bitbucket and start a pipeline from there seemed inconvenient, so we wrote a small plugin that does the job.
Finally, the workflow for designers looked like this:
Using a Git repository for design tokens brings several key advantages to DS workflow. Git automatically tracks every modification, creating a complete history of changes. Nothing gets lost or overwritten without being recorded — every color change, spacing adjustment, or typography update is preserved in the version history. Through pull requests, team members can review token modifications before they’re merged into the main branch. These pull requests can trigger automated checks that validate token syntax, generate visual previews of affected components, and run compatibility tests.
It is quite useful to adopt
Designers fill in a new semantic DS version number (major.minor.patch) and text description. When tokens are imported from Figma, we parse this information from Figma API and detect new version information. It is stored in Git commit as a version-x.x.x tag and an explicit “version” token. When creating platform-specific code, we can include a version token that helps track the design system’s current version. This makes it easy to match assets or communicate with APIs using the exact design version.
Let’s finalize the whole process on a real example of two color tokens: color.border.primary and color.border.secondary. The picture below shows their Figma and Style Dictionary formats for dark and light themes. We are using references to the Core Color values to be more flexible: {color.white.base}.
The following picture shows the same tokens further transformed into iOS and Android variables and styles.
Having an automated token export is not enough — we also spent quite some time detecting hardcoded styles (for example, raw color hex values), finding obsolete tokens, and setting new tokens instead. This work required frequent ad-hoc consultations with designers and adding or editing tokens because the app is huge, and not all cases were covered by the initial token set.
We also set automatic checks to detect and prohibit hard-coded styles in the future and communicated to other teams to use new guidelines.
After finishing with token usage in the app code, the next move was to integrate DS into our content.
Here, you can read about how we use Contentful for onboarding and articles:
https://medium.com/flo-health/mobile-onboarding-evolution-part-2-d7c324c348fe
https://medium.com/flo-health/the-evolution-of-the-content-library-an-engineering-story-850b2bc53bb2
Previously, there were content types with various fields defining their styles: color pickers, numbers for sizes, and dropdowns with values.
We added tokens instead of raw values so that we don’t need to edit each content piece when a token value changes.
Here is an example of a DS button element in Contentful Live Preview where design tokens are synchronized through the S3 bucket (one of the outputs of the tokens export pipeline).
As you can see, all button parameters are semantic, there are no raw values, and in case of any DS updates, the latest styles will be synced automatically in minutes.
Building Flo’s automated design system has brought clear improvements, though it wasn’t without effort. Here’s what got better:
We get it — skeptics may ask, “Was all this effort worth it?” or “What’s the ROI?” While we can’t pinpoint an exact dollar figure, the payoff is evident in faster feature delivery, fewer design inconsistencies, and scalability. Yes, it took time to set up the pipeline, reorganize files, and get the team on board. But the foundation we’ve built will save time and headaches in the long run.
This is just the start. Here’s what’s next:
While we were writing this article, our colleagues already did a POC with tokens as variables, so it is time for us to catch up and share our knowledge after migration is completed.
Figma variables make mode switching so comfortable!
Building a design system isn’t a one-and-done project. It’s a continuous process, and there’s still work to do. But we’re excited about the progress and confident it’s making a real difference.
Those who bravely read till the end, please post your idea for the Flo design system name in the comments.
Written by
Based on a tech
Design review by__Alexander Gavrilenko__.