Extending our design system to multiple platforms

By Shaun Donnelly
Backpack is Skyscanner’s design system. Like many design systems, it’s a collection of reusable components and guidelines for creating products that adhere to our style.
Until recently, in terms of code, Backpack mostly consisted of a collection of Sass mixins and various React components. Both of these were designed for usage on the web.
My colleague Szabolcs recently wrote about how we’re experimenting with React Native as a way for web engineers to contribute to Skyscanner’s native iOS and Android apps. As part of this, Backpack needed to expand to support React Native. Here’s how we did it.

Tokens

Backpack uses design tokens. Think of them like key/value pairs for foundational level styling items, such as font sizes, colours and spacing.
Our tokens are used heavily as a source of truth for most of our variables. We define tokens in JSON, then use Salesforce’s Theo library to change them into a format that can be used in components.
For example, here’s the file where we define tokens used in the button component. Theo transforms these tokens into usable values, like this Sass file, which is then imported and used in components.
We find tokens really useful and we were keen to continue using them in React Native. So, we adapted the tokens workflow to support multiple platforms. We abstracted tokens that could apply to all platforms (e.g. colours) into a common folder, then created separate iOS and Android folders for things unique to each platform (e.g. spacing). Then we adapted the build process to output token files for iOS and Android. React Native doesn’t support Sass, so we output the files in JavaScript.

A native development environment

Now that tokens were sorted, we had to adapt Backpack’s codebase to support developing React Native components. On the web, we use Storybook as a development environment. Fortunately, Storybook has a React Native versiontoo. It works with the simulator/emulator, as well as real devices.
We set up some scripts to open the development environment, as well as instructions for how to get the environment installed. Then, we were all set for developing native components.

Our first native component

We decided to make a text component first. This was a great one to start with, as the code review process allowed us all to try React Native and learn how to develop for it.

The current state

Five months in, we now have over a dozen React Native components (with more on the way) and engineers across Skyscanner are using them to build cool things.
The codebase is in a good place now to handle any future platforms Backpack needs to support. If we added a new platform tomorrow, the ramp-up time would be much shorter thanks to the foundational work we undertook with tokens.

Traps and pitfalls

Our journey to native nirvana wasn’t completely smooth. As when working with any new platform, there were quite a few quirks to figure out.

Make things for iOS and Android together

Initially we developed components for iOS first and Android later. This caused us untold headaches, as while React Native does standardise many aspects of the two OSs, there are still many areas where the platforms differ.
Designers also feel the pain when isolating platforms too. Being able to consider how a component looks and behaves across both iOS and Android minimises changes to the other platform further down the line.
Now, we design and develop for both simultaneously. If you do one thing, make it this!

Embrace platform conventions (when appropriate)

iOS and Android have strongly established conventions. For example, Android buttons tend to be written in uppercase, so our button component matches this.
However, diverge from the standard where it makes sense. If you follow every convention, your components will fit in, but won’t stand out at all. In the button component we used our brand colours, rather than the OS’s standard ones.

Code samples are hard

On the web, our docs site has live, interactive code samples. We can’t embed native components on the web, so for the moment we’re using screenshots.
This isn’t a great solution and we hope to address it soon. React Native’s docs site uses Expo to embed a virtual device, which is pretty cool.

Learn how to use the debugger

React Native’s element inspector is quite inferior to the ones found in Chrome and Firefox, but you can use Chrome and Firefox to debug the actual JavaScript.
Furthermore, you can dive into Xcode or Android Studio whenever you want to use their ridiculously powerful debuggers.
One last thing: console.log doesn't show up in React Native apps, but console.warn does.

Summary

Adapting Backpack to work with multiple platforms was much less hassle than we initially feared. We’re really pleased with how it’s worked out so far.
Backpack is open source, and we’re always happy to hear from members of the design systems community. Get in touch if you have any questions, advice or just want to say hi.

SEE the world with us

Many of our employees have had the opportunity to take advantage of our Skyscanner Employee Experience (SEE) — a self-funded, self-organized programme to work up to 30 days during a 24 month period, in some of our 10 global offices. There is also the opportunity to work for 15 days per year from their home country, if an employee is based in an office outside of the country they call home.

About the author

I’m Shaun Donnelly, a Software Engineer working in the Backpack squad in London. We’re an enablement team who create beautiful, accessible and reusable UI components for our colleagues to use across Skyscanner. Outside of work, I love cooking, JavaScript and complicated flight itineraries, in that order.
Shaun Donnelly - author