- read

Building Obsidian, Tinder’s Design System

Tinder 12

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.

A user interface with the Tinder logo at the top, a profile photo of a woman, her name and age, and a set of icon buttons representing actions like swiping left and right.
An early version of Tinder

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.

6 lines of code defining the style of a button in Swift

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:

  1. 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.
  2. 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.

Introducing Obsidian

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.

Twelve background and border tokens taken from the Obsidian Design Library in Figma including Dark and Light mode adaptations.

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.

Diagram with Figma on the left, Style Dictionary in the Middle, and GitHub on the right. Bidirectional arrows between each tool.
Styling data can flow in either direction, from Figma to our GitHub repo or vice-versa

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.

A screenshot of a JSON file named Palette.json containing the following data: { “Base”: { “Transparent”: { “value”: “#00000000”, “type”: “color” }, “White”: { “value”: “#ffffff”, “type”: “color” }, }

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!

A screenshot of Kotlin code titled ObsidianColors.kt defining an object with 5 color names and associated hex values.
A screenshot of Swift code titled TUIColor.Swift defining an object with 5 color names and associated hex values.
A screenshot of TypeScript code titled palette.ts defining 5 color constants with associated hex values.
Token code generated in Kotlin, Swift, and TypeScript by Style Dictionary

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.

A screenshot of JSX code: <div className=”C($c-ds-text-primary) Bgc($g-ds-background-brand-gradient)”> … </div>
Assigning a <div> the color token “Text Primary” and gradient token “Background Brand Gradient”

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.

Example of visual output from token lookup tool when hex code #f1786ff is input. The output display shows 9 token suggestions pulled from the Obsidian library.

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.

Side-by-side comparison of the sexual orientation selection screen before token consumption on the left and after token consumption on the right with increased color contrast.
Contrast is improved, making the interface more accessible for everyone but particularly for those with visual impairments

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.

A screenshot with the header “Dual Slider”, a code snippet for importing the DualSlider React component, a sentence describing the purpose of the DualSlider, and an example Dual Slider component.
The DualSlider component in React

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!