How we organise our Design System libraries to help Doctolib designers use more than 70 000 components a week
Figma Librairies are the invisible backbone of our Product or Brand Designers’ daily delivery. This means they must not be neglected, even more when your team is scaling fast, as we are at Doctolib.
Just to give you a few pieces of information in our case, we are currently 25 Product Designers, 10 Brand Designers, 4 UX Writers, as well as 2 Product Designers dedicated to Oxygen, our Design System. All our teammates are inserting more than 70000 components within a week! 😱 So, librairies really need to be cherished, refined and kept clean.
The logic behind Files and Libraries
The first key element to have in mind is to keep everything clean, well organised and easily accessible to designers. All the Design System related files are located in a specific project on Figma, with a dedicated cover for a quick identification. Six libraries used for our Design System are located on this project (with the black pen nib icon).
We have some small guidelines concerning our libraries:
- All libraries are activated by default on all our files (could be done via the settings of your organisation plan). This way, we’re sure that when a file is created, the designer will have access to all the resources we have in stock.
- One library serves one goal. Meaning we prefer having multiple libraries than a monster one containing everything.
As mentioned on the image above, each library has an owner, meaning someone (or a group of people) who is accountable for the “ health” and the maintenance of the file. Editors have the ability to edit components and publish libraries, and users can only use the library without being able to edit the components or styles in it.
Core vs. Domain components
A few months ago, all our components were located in the Components file. This file contained all types of components (generic, specific, localized, developed…). The growth of the team raised more and more issues and concerns:
- We faced failures, such as accidental deletions or overrides, and even if each component is flagged depending on its status (live, design only, deprecated, dev ongoing…), we regularly had misalignments.
- We also had lots of questions: Should a designer craft their own component or use a local one? Should this component be shared with other designers? Will this component be used by the whole team?
- We also asked ourselves what about components that are not meant to be developed, but only to design faster, such as side panels.
So, we decided to split into two distinct files:
- Core components: includes the generic and agnostic components, developed in React and live in production. The Design System designers own the file, manage the maintenance, add new components, deprecate and publish the library.
- Domain components: these ones are Figma only components and are not meant to be developed. They are mainly templates or complex organisms with variants (notably languages), and created to speed up the workflow of Product Designers. Each Product Designer is the owner of a frame with all the components related to their Feature Team. Thus, Product Designers are accountable for the publication of their own components.
In addition to generic components, the Core Component file contains some UI kit components, such as iOS and Android native elements (keyboard, top bars, status bars, browser interface, menus or notifications), and a Toolbox, with components dedicated to ease the workflow of designers, and help organise files like section headers or sticky notes.
Figma files organization’s tips from the Doctolib team
Fact one: Figma is THE design tool of the Design Team for more than a year now at Doctolib. Fact two: our team has more…
So, finally our Design System is centered around 3 files:
- Foundations and Core Components, with all the basics and managed by the Design System Designers.
- Domain Components that are product specific and managed by Product Designers.
Domain Components in detail
Core components and Foundations are quite easy to comprehend, it’s a bit more tricky with Domain Components.
As you have understood, whereas Core and Foundations set the basics, Domain components are closer to real life and adapted to the product itself. That’s why we took some time to build this file, and notably the structure and the nomenclature.
We chose to create a Frame per Feature Team and not a Page on purpose:
- We have more than 50 Feature Teams, and lots of them work on interrelated topics, so it helps designers to have an overview of all the components within the same product (and we also avoid having uncountable pages…).
- It assigns clear ownership on each component. For any issue or improvement (maintenance, craft, deprecation…), any designer will know who has created it and can sync directly with this designer.
- It facilitates browsing in the libraries.
About this last point, we have today around 900 shared components (550 icons / 160 core / 85 domain / 150 illustrations — variants excluded from this count), so finding a component is starting to become a challenge. With this structure, we help designers easily import their components while browsing through all libraries.
In the image above, whatever the term you used to find your component, it will be listed. In this fictive organisation, there are 4 use cases to find a component called Billing Card:
- The designer knows this component is based on a Core Component: Card. Results will be Core components +organisms made with Core components
- The designer is looking for a component related to Billing without remembering the exact name. By typing approximately the name of the component, the Billing Card will be listed.
- The designer knows the name of the Domain but not the name of the component or the precise Feature Team. The results will be the Domain components in the page Domain C.
- The designer knows which Feature Team created the component (in the image, BAP stands for Billing and Payment, and is a fake name). It’s also a good way to find all the components of one specific Feature Team.
You may noticed we have a specific nomenclature for Domain components: [Instance name] 💠 [Core name]
It helps us understand instantly which component depends on a Core component. In case of a complex organism with multiple Core components, we remove the last part of the name. In theory, this should not happen because the organism must be a Template hosted on a Core component.
So, where should my component be located?
This is a question Product Designers ask regularly. Let’s try explaining with an example. In our product, the patient’s medical history is composed of a timeline, and each event in this timeline is a card that relies on a specific cluster (cardiologists, gynecologists, nurses…). Clusters are managed by different Feature Teams, so the impact on the timeline is that it is composed of components shared by different Feature Teams. But each cluster has specific needs. For instance the Feature Team managing Gynecologists need to specify the dates of the pregnancy which are not at all useful for Cardiologists.
Concretely, how is it managed on the Design side?
- Designers from different Feature Teams agreed to create a template (molecules, organisms…) based on the atoms offered in Core Components.
- These templates must be hosted on a dedicated page of Core Components (called Template), and must contain a swappable area.
[History_card] in our example.
- Once this template is published, each designer can reuse it by adding another nested component they created, which is hosted on the Frame corresponding to their Feature Team on the Domain Component page.
[Gynecologist History card & Cardiologist History Card] in our example.
This way, we can have similar but modular components, without detaching instances and thus generating design debt, but also tech debt.
Oxygen Playground: where magic happens ✨
The Oxygen Playground file is not a library in itself, but it is intimately connected to the Core Component library. This file is where we’re crafting new components or iterating on existing ones. Basically, this is the only place where our designers are largely encouraged to detach instances (you won’t often hear these words come out of my mouth 😉).
To avoid having a heavy file, we split this file in branches. One branch is dedicated to one and only topic.
Process is: once a component has been reviewed and validated by the design team, this one is being developed by a Feature Team, published on Storybook, then we ensure to have all the refined guidelines and specs in Oxygen.
The final step is to migrate the component from Playground to Core component and officially publish it in the library. In case of a component improvement, a deprecation of the old one is a mandatory step.
To conclude, here are a few tips to manage your Figma libraries without any frictions.
First, be clear on rights, permissions, ownerships from the start. What works for a team of 50 designers works for a team of 2, but the opposite is not true. Put the rules in place from the start to avoid complications when your team scales (because it will 🙂).
Second, stick to the one library one goal mindset. In our case, when all our components were in the same files, in addition to the issues mentioned above, it generates lots of questions: Do I have the right to publish my domain components myself? Should I publish the entire library or just my components? I want to create complex organisms but don’t want to pollute the component file… Another issue to keep in mind, this file will always grow and so will its weight. So, for maintenance and smoothness of the workflow, it’s definitely a good thing to split everything in several libraries.
Three, include everyone and synchronize. On our side, the Brand Design team is managing their own libraries of illustrations, but it has an impact on some of our core components, notably a largely used placeholder component that facilitates our Product Designers’ workflow. It’s key to interact with the managers of each library to be sure not to break a component or a usage when publishing a change.
Four, be smart when deprecating components. Definitely something that needs to be highlighted. When a component needs to be replaced or modified, there are three use cases:
- Really few instances among all the files (less than 30 or 50): replace the old component with the new one in the library, and directly in the concerned files.
- Quite some instances (up to 200): add a deprecated pattern on the old component, add an underscore or dot in the name (to hide it from the library when importing a component), ask your team members to replace the component each time they spot one in a file.
- Many instances (>200): adding a deprecated pattern may lead to weird designs and create fear for the other users of Figma (PMs and devs), so take the same process as above, without adding the deprecated pattern.
All this work wouldn’t have been possible without the huge help from my partner in crime Michael Blancon Tardi, and the marvelous Product Designers team from Doctolib