Code with Design — How we Built a Tool to Export React Prototypes from Sketch

Joel Besada
Jan 15, 2018 · 7 min read

Every year, right before the holidays, we dedicate a week of our time at Tictail to do something that is not part of our normal work. We call this the Demo Week, and it’s a great opportunity to explore new ideas and collaborate with people you usually don’t get to work with. This can be a new experimental product feature, an improvement of a company process, a LED map of live purchases, or anything else that would improve Tictail. As the name implies however, it needs to be something that can be demoed at the end of the week.

This year, me and designer Petter Nilsson decided to explore the possibility of building a tool that connects the workflows between design and development. More specifically, we wanted to build a tool that can export our Sketch designs into fully interactive React applications. Like Airbnb’s React Sketch.app, but the other way around!

Now this might sound like a huge project to finish in just a week, but we decided on a couple of limitations of the tool to make this possible:

  • The design in Sketch can only consist of pre-defined Symbols that map to our already implemented React UI components.
  • The exported code will only serve as an interactive prototype to showcase the app layout and flows between different screens, similar to what Framer aims to do. The code can be used as a starting point for production implementation, but it won’t contain any real production data or business logic.
  • It’s possible to export a responsive layout, but the designer will need to do the heavy lifting of figuring out the structure of rows and columns by defining those as named groups in Sketch.

Here’s what we ended up with by the end of the week:

Considering the limited time we managed to get quite far along the vision that we set out to accomplish. In this blog post I’ll try to give a high level description of how we built this tool.

Reading Sketch Files

{
document: {...},
meta: {...},
user: {...},
pages: {...},
}

The most interesting part here is the pages object, which contains each page in the Sketch document as a tree of layers. A layer can be a group, text component, symbol, rectangle, etc., with each layer possibly having more child layers.

The loader also uses Webpack’s emitFile API to make any of the bitmap images available by their paths on the development server. Lastly, since most of the text data is stored as binary plists, it unpacks these fields to make them readable in the client. You can view the loader in its entirety in this Gist.

Components and Props

A layer in Sketch is for the most part either a Group (a folder of child layers), or a pre-defined Symbol (e.g. a button or select box). We also have special handling for Image and Text layers. The groups follow an agreed upon naming convention that we can parse to map them to container components with spacing and alignment props.

To be able to set all the props of UI components, we slightly abuse Sketch’s Symbol Overrides feature. In the example below we have a label field that’s visually represented in the Sketch document, but we also have a number of hidden fields that are only used in the mapped React component.

These fields are automatically set from the selected option in the dropdown field. The button symbol that we created in Sketch comes with a number of different types and states, so you can for example select between secondary and primary buttons, and whether the button is disabled or not.

Layout

While it would have been very easy to read the dimensions and coordinates from the Sketch document and absolutely position everything, we decided that an important feature for the tool was the ability to make the exported app responsive.

We’ve often run into situations where we have a beautiful design for the standard mobile, tablet and desktop sizes, but once you start resizing the window between these breakpoints you may find various issues that weren’t anticipated in the design. This happens because the designer doesn’t have the tools to view the design in all possible in-between sizes before it has been implemented by the developer.

To make this possible, we decided that it’s up to the designer to structure the design in terms of rows and columns that adhere to a standard 12-column grid layout. This task is something that is usually left to the developer when it’s time to implement the design, but given the right tools it makes more sense to have this step figured out already in the design process.

All the designer needs to do is to create groups named Row and Column that the elements are placed within. As with most grid layouts, a row can consist of multiple columns, and columns can themselves contain their own nested rows, continuing down recursively as far as you wish. When the code loops through this structure it can automatically detect the intended sizes for the columns, and by looking at the different screen sizes that there is an artboard for, we can map these values to their corresponding breakpoints.

Benefits

Having a more tightly integrated workflow between design and development comes with some huge benefits:

  • The feedback loop for designers is vastly shortened since they don’t need to wait for the actual implementation or build prototypes using other tools to test the user experience.
  • Time spent designing contributes to the production code, since a whole lot of trivial implementation time can be saved by basing the code on the work that the designer has already put into defining the layout and components.
  • By having a one to one mapping between UI elements in the design and the implemented React components, the designer can gain a better understanding of where current code can be reused and where new components need to be implemented.
  • Giving the tools to define how an app should behave responsively allows the designer to contribute to figuring out how components fit into the grid on different sizes, rather than leaving all of that responsibility to the developer.

Moving Forward

Since the tool is heavily coupled to our own UI components, there is unfortunately not much of it that we can share with the rest of the world. But fear not — there are already a ton of interesting open-source tools that are starting to pop up within this space:

It will be interesting to follow the progress of these tools, and we are excited to see how we can incorporate this into our design and frontend development workflow.

Tictail - Behind the Scenes

Thoughts on product development from the people of Tictail.