Building Obsidian, Tinder’s Design System
Author: Darragh Burke, Software Engineer II, Web Development at Tinder
Tinder’s UI Opportunities: Wildfire
When Tinder first launched in 2012, it pioneered a brand new user experience: the Swipe Right® and “Swipe Left”™ features. The app’s simplicity was a big part of what made it so appealing.
We’ve emphasized building new features and moving fast while growing, but a decade later, Tinder has become a significantly more established app. It’s become harder to maintain consistent design practices across every screen and component and the codebase suffered too.
The cost of designing, building, and maintaining features was becoming unsustainable. We needed a way to unify the appearance of the application, save time for product managers, designers, and engineers, and deliver a more consistent appearance to our end users. We needed a design system.
What is a design system?
Using patterns in designing software isn’t a new idea — it’s been around since at least the 1960s. But it was Brad Frost who popularized the phrase “Design System” with his 2016 book Atomic Design.
A design system is essentially a standardized collection of styles and reusable components that dramatically reduces the cost of design and development and increases the quality of an application.
One common idea across many design systems is the notion of “Design Tokens”. These are tiny bits of design data that can be used to build interfaces. Design Tokens can consist of colors, gradients, font faces, border radii, or any other value that’s used in a UI.
We think of design tokens in two categories:
- Base Tokens. These directly reference styling data like colors or font sizes, and might be named something like “Blue 15” or “Brand Primary”. The name describes the value inside. We don’t think these should be used in designs directly, as they contain little semantic information about the purpose of the token.
- Context Tokens. These tokens reference other tokens instead of raw values directly. They contain information about where they should be used. They can also contain theming information — they can map to a different token depending on the theme the user is in, such as light mode or dark mode. For example, a token called “Text Primary” might map to Black in light mode and White in dark mode. This would result in dark text in light mode and light text in dark mode.
By using context tokens to build interfaces, it becomes trivial to enable dark mode or even other types of themes. It also means that all styles are controlled from a single place, so it’s easy to update a style and see it reflected across the entire application.
Using standard tokens also lets us craft styles carefully for accessibility. For example, we can define sets of matching text and background colors that will make our application more accessible to those with visual impairments. By using our defined pairs of background and foreground tokens, consumers of the design system can feel confident that their designs will meet contrast requirements.
Finally, tokens help to align design and engineering on a common language for talking about styling. Rather than describing “that black text color”, we can simply reference the “Light/Semantic/Text/Primary” token. This resolves ambiguity and ensures everyone is on the same page. If we think of a user interface as a cooking recipe, then design tokens are the ingredients — and it’s much more helpful to call for “butter”, a concept everyone understands, rather than “triglycerides”.
Another core feature of a design system is the idea of reusable components. These are UI elements such as text inputs or checkboxes that have a predefined set of styles and can be dropped in anywhere. Designing and building reusable components can be a huge time-saver in the long run, reducing the amount of work for both designers and engineers to build features.
There were several attempts to introduce these ideas to Tinder over the years, but they always came up a little bit short. There was no single, cohesive design system for Tinder until the UI Platform team was officially formed in 2020. This was a team whose explicit purpose was to create a set of design standards that could be used to build features at a faster pace, with more consistency and accessibility. Ultimately, the vision we settled on was this:
“Empower our designers, product managers, and engineers to move fast at scale while reducing operational cost of creating new experiences.”
We built Obsidian to realize that vision.
Obsidian is Tinder’s Design System. It’s an entire design ecosystem composed of a set of standardized design tokens, reusable UI components, documentation, and design tools. It exists to resolve ambiguity in the design process.
The Figma plugin Tokens Studio was the first key piece of Obsidian. This plugin enables us to define tokens for everything from fill colors to border radii. A set of documents in Figma contain every Obsidian token. Thanks to Tokens Studio, they can then be used in designs across the app.
Tokens Studio enabled designers at Tinder to make use of Obsidian tokens in all of their designs, but we wanted to bring the power of tokens to our engineers. Tinder has an iOS, Android, and Web app, and we needed to ensure consistency between each platform. That’s where Style Dictionary came in.
Style Dictionary is a framework that enables transforming styling data from a single source of truth into platform-specific artifacts that can be consumed by other codebases. We wrote a script to translate our Tokens Studio data into a format that Style Dictionary understands, and from there we just needed to write transformations to generate the code needed for our client platforms.
Style Dictionary then generates artifacts for each platform. These can be dropped into client codebases, enabling engineers to reference design tokens in their code — and because the tokens are defined statically, you get code completion!
Of course, the way the design tokens are consumed varies by platform. In Tinder Web, we were already using Atomizer, which generates static stylesheets at build time containing classes with all the styles you’re using in your application. Atomizer lets you define custom classnames, so we built in a method for developers to easily use tokens in the JSX they’re constructing.
The beauty of this infrastructure is that if we want to release a new token or update an existing one, we can simply create it in Figma and then publish a new version of Obsidian. Two bash scripts and we have new artifacts that can be plugged into each of our codebases. Because there’s a single source of truth, we never have to worry about inconsistencies between platforms.
This system also makes theming incredibly easy. We can simply reference context tokens inside of our client codebases. These context tokens are automatically resolved into the appropriate base token and then the underlying value. When the user switches into dark mode, we can simply resolve the dark version of each token instead. But more to come on that later!
We built a shiny new infrastructure to support design tokens, but we weren’t building a new app from scratch. We needed to integrate the tokens into our existing applications, each of which had thousands of usages of hex values, font faces, and other styles. We needed an easy way for designers and engineers to find the right tokens to replace the raw values they had been using. To support this work, we built two things.
First, we created a comprehensive documentation site using Zeroheight. Zeroheight is a tool that’s tailored specifically to design system documentation. It enables us to pull tokens directly from Tokens Studio and display them in an easy-to-read interface.
In addition to an exhaustive list of tokens, we wrote more than 100 pages of documentation guiding designers and engineers on where and how to use design tokens.
Secondly, we built a token lookup tool that allows developers to search for tokens by name as well as by value and type. For example, if an engineer is looking to replace text with the raw hex value “#1786ff”, they can paste the color into the tool, and then filter for only tokens with “text” in the name. Once they find the token they want to use, they can expand it to get a list of code snippets for each platform that can be pasted directly into the code.
With the tooling in place, we launched a large effort to migrate to design tokens on all three client apps. What were the results? Well, we’re still in the process of this migration — but we’re already starting to see the payoff of design token usage everywhere.
This example might seem small, but these little fixes replicated across hundreds of screens on each of our apps helps create a more beautiful, consistent, and accessible interface.
Obsidian has also made it much easier for designers and engineers to collaborate and ship faster. Siddharthan Asokan, a Senior iOS engineer at Tinder, had this to say about Obsidian:
“I used to work on features before the design system was in place. I remember pinging, and walking to the Director of Product Design’s desk every time to figure out the colors, font size, line height, padding, etc. We used to have long design bug bash sessions where I pray for no big changes. Recently I worked on contact exchange proactive screens with the design system components. There was no big change request, everything was an easy drop in and that kept me sane. I really appreciate the work you guys have put in.”
Obsidian is already a powerful design system, but we’re still just getting started. We have a laundry list of features we’d love to add — including an iconography library and the ability for feature teams to contribute tokens back to the library. We’re excited to keep accelerating Tinder’s development and building a more beautiful application for our users! We’re also in the process of building out a set of reusable UI components that will greatly reduce development time for new features.
This is the first in a series of posts about Obsidian. Stay tuned for the next update, where we’ll share how we used the tools we built to craft Dark Mode on Tinder Web!