We introduced Sushi, Zomato’s in-house design system, to the world in 2019. Since then, the positive reactions we’ve received from the design community have been nothing short of amazing. Moreover, the feedback and learnings we’ve garnered from the products built over the past couple of years have been extremely fruitful, and have helped us evolve Sushi beyond what we had initially envisioned for our design system.
We also know that building a design system for one’s own organisation can turn out to be a very exhilarating process. If you are attempting to build one, feel free to try some of the steps we followed at Zomato to get as close to the system as we had imagined to create.
We hoped to build a system that would not only support consistency across our products, but would ensure better onboarding, and design collaboration between teams.
Let’s take a deeper look at how we built and scaled Sushi.
As we grow, we adapt to the dynamic customer requirements by constantly modifying or adding new features to our products.
To keep pace with such a process, we felt the need to build a library that could be referred to for reusable elements, as opposed to creating novel ones every time we decided to enhance an existing product, or develop a new one.
Problems that our initial approach caused –
- Customer confusion – Different patterns or components responsible for the same action confuse customers.
- Slow design and development process – Lack of reusable design assets slow down designers and developers as the elements are then required to be created from scratch.
- Onboarding difficulties – The onboarding of new designers and developers is a tedious process, and does in fact become more time consuming with an elaborate training.
The big question was
How can we ensure an all-encompassing positive experience for customers, designers, product managers, and developers?
The solution was
To build a design system that helps release and test new features better, and increasingly faster.
To accomplish this, we followed these steps –
- Auditing the UI inventory
- Formulating the design system foundation
- Creating component libraries
- Governing the system
- Building support for all platforms
- Mapping workflows and onboarding
1. Auditing the UI inventory
Instead of starting from scratch, we took a deeper look at what we had created in the past. We had a collection of unlabelled components such as typography, colors, layouts, sizes, etc. This gave us something to start with.
Compiling these components made it easy for us to monitor overlaps, or in other words, repeated application of patterns. Additionally, we spotted components that had been used only once, and therefore didn’t have to be accommodated in our style guide.
1.1 Kickstarting the audit
Brad Frost (author of Atomic Design) suggests that the process to build the inventory should start by consolidating screenshots of the product interface, and then categorising them into chunks. Here’s how we achieved this –
2. Formulating the design system
Post the UI audit, we had a basic style guide ready with colours, typography, icons, spacing, shadows, information architecture, etc. These helped us create unified and reusable components that formed the foundations of our design system.
Read more about how we came up with our design system’s foundations in our previous post.
2.1 Naming conventions
A fundamental part of any design system is how we name our styles and components.
Without a proper naming convention, designers, product managers and developers, struggle with the effective labelling of different components. Our primary goal was to seek a scalable naming convention that not only had room for known elements, but also took into account future additions.
This approach included the usage of generic names in a more abstract format, such as xsmall, small, medium, large for typography or lighter, light, darker for colour. Even though this was easy to recognize, but was not scalable after a certain point.
Here, we added incremental numbers to names, such as Red1, Red2, Red3 and so on.
Though this was better than our first solution, it turned out to be complex when we added values between two adjacent places.
For example, if we wanted to inject a new tint of Red between 1 and 2, which would technically be 1.5 (or anything else in between), it became harder to handle or maintain.
This approach allowed us to easily inject values between two adjacent places, as we kept a considerable amount of gap between two values. For example, between 10 and 20, we had room for nine different tints to be injected.
Solution 4 (we are using this)
This approach was similar, but better than solution 3 as it gave us more room to scale our values with gaps of 100 available between two adjacent places.
Colours are one of the most important building blocks of any interface. Thus, it was imperative for us to clearly define all the colour tints in our design system.
During the UI audit of our existing components, we were rather shocked to discover that we had over 20 tints of grey!
While we’re aware that one should have various colour tints in their product, it’s not a good practice to exploit that freedom by utilising just any colour for different use cases.
Brand guidelines always have primary colours, such as Red, Blue or Black. However, UI design requires multiple tints, and tints of each colour to effectively apply them.
This also raises the question – how many tints should ideally suffice here?
Here are some key actions we took while creating our colour system –
- Scaled our colour names between 100 and 1000, such as Red 100 and Red 900, in order to inject new colour tints in between. Tint 500 was used as the base colour everywhere.
- Generated colours based on HSL to ensure a harmonious colour palette
- Validated colours with WCAG 2.0 rules in order to maintain contrast and accessibility
- Bucketed all colours into primary and secondary groups. Each colour had 10 tints, which were generated with the help of HSL colour conversion.
Typography is another very important aspect of design systems. How we utilise font families, size and weights in our design depends heavily on typography.
Every font family has a specific design intent and communicates certain attributes. There are many fonts out there and all fall into four basic font categories – serif, sans serif, script and display/decorative. And choosing the right font for a design is very important.
For Sushi, we decided to use Metropolis – An open-source geometric typeface. We modified it according to our system’s requirements and named it Okra.
Here are some key actions we took to create our typography system –
- Followed the same scalable naming convention as we did for colours in order to easily scale our typography names between 100 and 1000
- Line height, letter spacing, and font weight were well defined, and HIG or Web standard guidelines were followed
- Responsiveness was a key factor in formulating our typography system. For example, font size 13px on Mobile was mapped to 16px on Web
Here is a great article on Typography by Tim Brown (CEO of the design firm ‘Ideo’).
Icons are of prime importance because customers can be immensely motivated to perform an action by simply looking at an icon.
For a long time, we had been using different icon font files for iOS, Android, and Web. We were updating more than 500 icons separately on all platforms. However, the ideal way was to go ahead with a single set of unified icons to serve all platforms.
So, what did we do?
- We audited all icons and removed the unused ones
- We created a new repository called Wasabi, and it goes extremely well with Sushi
Now, we have a single file serving all platforms including iOS, Android and Web. All our icons are curated using Adobe illustrator and Figma, and the svg icons are then converted into font file using Fontello.
Spaces are needed everywhere when it comes to design, specifically in the form of padding and margins.
Spacing not only helps create new components, but also assists in arranging combinations of existing components. These settings are defined as variables.
Spacing values are usually factors or multiples of the baseline grid number, and an 8-point baseline can work well for all kinds of platforms. So, our spacing values were decided based on this pattern – 2, 4, 8, 12, 16, 24, 30, 32, 36, and so on.
While building Sushi, ~6 to 8 values seemed to offer enough variance and were sufficient for a complex product as well, but one can always add more intervals if they feel the need to.
Our spacing values were finally fixed at – 2, 4, 6, 8, 12, 16, 24, 32.
By streamlining spacing values, the designer-developer handoffs became faster, and developers were able to effectively predict spacing in mocks shared by designers.
3. Creating component libraries
Components help designers work in a consistent way, and are used repeatedly throughout the development of a product.
How do they help?
- Easy usage – Component libraries have ready-to-use components that can be utilised throughout the journey of a product
- Fast development – Since these are easy to use for developers, they ensure an increased delivery speed
- Efficient collaboration – Anyone can pick up components from the component library and create their own solutions
- Consistency – Since all stakeholders are referring to the same libraries and are using the same components, the usage remains consistent throughout
- Customization and flexibility – Most of them follow a certain business logic that is integrated within them, and are open to adhering to new ones
3.1 How to create, contribute and add new components
Though we have a large set of components available in our repository called the library, sometimes the solutions to certain problems require us to design new patterns in our products.
We analyse all new features and components for every such request we receive by asking the following questions –
- Is this a new component or just a modification of an existing one?
- Why don’t the current patterns support this use-case?
- How can we use this component beyond our current scope?
To build a new pattern, our designers create components with the help of foundation elements and existing low-level components from the design system. Post this, our developers start building, testing, and releasing these components with proper documentation. Meanwhile, a Figma change log is also created to update the component library.
Instead of fighting new additions, rig your system to tolerate a bit of experimentation. Then make it easy to incorporate the experiments that work.
4. Governing the system
The design system helps us create a better design culture where everyone can contribute to its continued development. This results in building inclusive customer experiences, as well as in achieving business goals faster.
We must govern our design system. We need to ensure that the highest standards of quality and accessibility empower our designers.
At Zomato, a design development platform team helps us build, govern and manage this system with a goal to design and build faster, keeping consistency in mind.
5. Building support for all platforms
iOS, Android and Web platforms have their own specific requirements. The design system must have rich components in place to fulfil the requirements of these platforms.
Initially, we started to build our design system solely for mobile platforms, but later moved to Web as well. We used Figma to create responsive components that can easily scale up and down depending on the screen size.
Every designed component of Sushi is developed and managed by our platform team in native tech frameworks. We built our Web components in React, which is quite popular with design systems these days.
6. Mapping workflows and onboarding
Most of the work involved in building Sushi helped bring people together, along with shipping products faster, and more effectively. It also reduced the amount of time it took for new members to get trained and adapt to the processes we follow internally. Now –
- Product managers can create a pixel-perfect interface with reduced effort
- Design team members can collaborate and design with the latest design components
- Developers can conduct rapid prototyping with clickable prototypes
Building a design system is an endless job, rather it’s just the beginning of a job. The ecosystem gets optimized version by version as we continue to ship new products and features.
Currently, we are utilising v3 of Sushi that offers a larger library of components, and higher flexibility to apply those as per our requirements.
Here’s what we are yet to do –
- Transfer all remaining products to the Sushi design system
- Integrate remaining interface elements that are still in the ideation phase
- Ensure that visible interface elements can be localized for multiple regions
- Update components for new upcoming feature releases