Sketch + Node.js: generating icons for many platforms and brands

Original author: Cristiano Rastelli
  • Transfer


There is nothing easier than adding an icon to the project: you just need to write to the designer, he will export it from Sketch and send you the option you need, and you use it in your code. If you have a dozen projects, several platforms and a lot of A / B design tests, then you just have to do the same thing, only 40 times more often and never make a mistake anywhere ... or try to automate the process. Under the cut - the first part of the translation of an article by my colleague Cristiano Rastelli about one example of such automation.

The problem we were solving


We at Badoo are developing a dating app. In fact, these are several applications, each of which operates on several platforms ( iOS , Android , Mobile Web , Desktop Web ), and several teams work on them.

In the development, we use hundreds of different icons. Some are the same in every application, others correspond to a particular brand. Sometimes the design changes, and the icons change with it: new ones appear, some are updated, some are deleted (but often remain in the code base).

Icons are created and maintained by our design team, and when the icons are ready for work, designers usually send them by email, chat or cloud. This not only took time, but also often led to errors. To be honest, there were errors every time (we are all people): sometimes the icons were updated on one platform, but not updated on another, sometimes they disappeared or did not match the format or size. Therefore, designers and developers were forced to be in constant contact; the developers exported the icons directly from the Sketch file, and they were added to the code base, but no checks were made for similar icons available for reuse in the database. I’m sure you understand what I’m talking about.

We at Badoo have a design system called Cosmos, and recently we introduced a multi-platform (Mobile Web, Android, and iOS) token library . In fact, now design changes (for example, the appearance of the button border, page background color, title size, or animation duration in the pop-up window) can be described using a set of parameters, which is then automatically exported and used in all applications on all platforms.

Our solution, which allows us to transform design ideas (for example, changing colors) into a functioning code in a short time, impressed our product managers and designers equally. Therefore, their next question (and at the same time the task) was: “Is it possible to do something similar for resources?” We answered: “Yes, it is possible (probably) .

I must admit that at first we acted blindly. We had several ideas, but considering all the restrictions, we were not sure that they would work. We decided to start with MVP, but everything went so well that the project became our final product with all the necessary functions.

Requirements


The requirements for the MVP project were clear: a tool that would receive a Sketch file at the input and output all the icons in all the formats we needed and support icon variations for A / B tests.

The difficulty was that the same icon has different parameters (color, shape) depending on the brand. Below are a few icons for our applications. As you can see, some are absolutely identical, others differ in a number of parameters, and still others have nothing in common.



Please note that the colors used in the icons are not just colors: they exactly correspond to the brand colors and specific features indicated in the tokens .



So, when developing the tool, our goal was not only to automate the creation and delivery of icons for different platforms and brands, but also to make possible their dynamic colorization in accordance with the brand.

Sketch and SketchTool


Sketch is the main tool of our designers. And, although we considered other options (for example, Figma ), we knew that in the framework of this project we would use files in the Sketch format (since our designers own this tool best and all our current icons and resources are saved in this format) .

In fact, at the beginning of the project, we were not even sure which file format was needed for the platforms. We imagined the process like this: export icons from a Sketch file in SVG format, then “feed” SVG files to versions for a mobile browser and Android, and for iOS find a library that converts SVG to PDF. This was the plan from the very beginning, although we had no idea whether our idea would work and what problems we might face. In fact, for this we needed MVP - to understand whether our project is being implemented, and, if so, how time-consuming it will be.

I don’t know if you had to work with PDF converters, but my experience says that this is a nightmare. They are always almostcope with the task, but never do it 100%. Therefore, the spinal cord, I felt that we were walking along a slippery path.

Exporting resources from Sketch is perfect - I never had problems downloading SVG, PDF, and any other formats. Therefore, I decided to find out whether it is possible to interact with Sketch in a different way - to export resources directly through Sketch, perhaps programmatically (I was also interested in whether you could create a custom plug-in, although this would mean a carriage of work for me who did not have such experience) .

I knew that the internal structure of a sketch file is essentially an archive. Renaming .sketch to .zip, you can open the file by double-clicking; in the resulting folder, you will see a list of JSON files and a preview file in PNG format.



So, I began to study JSON files in an attempt to understand how they are related.

I found that although they have a large degree of nesting (and are large in size), the relationships between different entities within objects are not so confusing. You have pages, artboards, and layers. Each layer contains paths that can have common styles. Each of these entities has a unique ID that allows you to maintain a connection between different files; and all pages are saved in JSON files and are contained in a subfolder of pages (the page ID serves as the file name).

During the study, I made an important discovery: the names of layers, pages and styles are just labels that can be changed at any time without disrupting the internal structure of the Sketch file. Only the unique ID attached to them matters, which is not shown to the end user (although you can read it and refer to it inside JSON files). Here's a sample of what a unique style ID looks like:

{
 "_class": "sharedStyle",
 "do_objectID": "49BA4E98-8D63-435C-81D9-E2F6CDB63136",
 "name": "name-of/the-style",
 "value": {
     "_class": "style",
     "endMarkerType": 0,
     "fills": [
         {
             "_class": "fill",
             "isEnabled": true,
             "color": {
                 "_class": "color",
                 "alpha": 1,
                 "blue": 0.7176470588235294,
                 "green": 0.4627450980392159,
                 "red": 0
             },
             "fillType": 0,
             "noiseIndex": 0,
             "noiseIntensity": 0,
             "patternFillType": 1,
             "patternTileScale": 1
         }
     ],
     "miterLimit": 10,
     "startMarkerType": 0,
     "windingRule": 1
 }
}

Therefore, I thought about the possibility of introducing conventions on the naming of artboards and pages, so as to inform some kind of meta-information about the relationship of resources and use them programmatically during assembly.

Sketchtool


Thus, when the initial study was completed, the plan “Export icons to SVG, and then convert ” turned into “ Let 's make a plug-in for Sketch that will directly export icons in the final format . However, even then the scheme of work was rather blurry (and not the fact that it is being implemented).

Studying the source code of existing plugins, I tried to understand whether they can interact with the export API from Sketch, and if so, how. And at that moment I came across a tool that I had not heard about before - SketchTool.

SketchTool is the official Sketch tool (i.e. developed by Bohemian Coding). According to the documentation, he
is a command-line utility that comes bundled with Sketch and allows you to perform certain actions with documents in the Sketch format, for example, check or export resources. It also allows you to control some Sketch features from the command line - for example, running plugins.

Wait, command line utility for exporting resources ? Exactly what is needed! In addition, since this is an official tool, there should be no problems with version compatibility, obsolescence, support, etc.

I began to study the utility and read all the documentation - the only page on the Sketch website (very few materials are devoted to it on the Internet, so it’s not surprising that I heard about her just now).

SketchTool is attached to Sketch, and it can be found at: By executing a Sketch.app/Contents/Resources/sketchtool/

command in the terminal $/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool, you will get the following result (I simplified the data a bit):

Usage: sketchtool  []
 [--formats=]
 [--use-id-for-name{=YES|NO}]
 [--export-page-as-fallback{=YES|NO}]
 [--serial{=YES|NO}]
 [--context=]
 [--application=]
 [--without-activating{=YES|NO}]
 [--item=]
 [--items=]
 [--safemode{=YES|NO} | --no-safemode | -S {}]
 [--max-size= | -m ]
 [--background= | -g ]
 [--compression= | -c ]
 [--new-instance{=YES|NO}]
 [--reveal{=YES|NO}]
 [--timeout=]
 [--include-symbols{=YES|NO}]
 [--bounds=]
 [--outputJSON=]
 [--filename=]
 [--wait-for-exit{=YES|NO}]
 [--scales=]
 [--overwriting{=YES|NO}]
 [--group-contents-only{=YES|NO}]
 [--trimmed{=YES|NO}]
 [--help]
 [--progressive{=YES|NO}]
 [--save-for-web{=YES|NO}]
 [--output=]
Commands:
dump               Dump out the structure of a document as JSON.
export artboards  Export one or more artboards
export layers     Export one or more layers
export pages      Export an area from one or more pages
export preview    Export a preview image for a document
export slices     Export one or more slices
help              Show this help message.
list artboards    List information on the document's artboards.
list formats      List the supported export formats.
list layers       List information on all of the document's layers.
list pages        List information on the document's pages.
list slices       List information on the document's slices.
metadata          List the metadata for a document.
run               Run a command from a plugin, inside Sketch.
show              Show the location of the various sketch folders.
See ‘sketchtool help ’ for more information on a specific command.


As you can see, the tool has four main functions:

read/dump- read / create metadata dump of internal JSON files,
list- create a list of file entities,
export- export these entities,
run- run the command provided by the plugin.

In addition to this, each command has several options available. In the case of export, almost all the options that can be found in the corresponding panel are also available on the SketchTool command line:



This means that SketchTool allows you to use Sketch directly for export (for example, from SVG to PNG or PDF) without resorting to external converters. Great!

A quick test using SketchTool and a regular Sketch file with several icons inside confirmed our guesses: thanks to this simple tool we can not use external programs for export and not write our own. Sketch can do anything!

Sketch File (s)


When we decided that we would use Sketch to store and export icons, it was time to put the icons used in our applications into a Sketch file.

Initially, we planned to work only with a limited set of icons created for an MVP project, but quickly realized that it would be better to collect all of them, in order to immediately eliminate duplication, inconsistency and other problems.

Our designers did a good job - and after a couple of days, the bulk of the resources used by them in Sketch files was collected in one file. At this stage, he looked like this:



Each icon in the file had its own artboard, named according to the desired icon name (subsequently, the same name Sketch will give the file resulting from the export of the resource). All paths are converted to paths, and combined paths are reduced to one shape. Thanks to this, the generated resources retain their perfect appearance (as in the source file) and are compatible with various platforms.



Dynamic colorization of icons using common styles (and token design)


The next step after collecting the icons was to apply the necessary colors to them. We created a set of predefined common styles ( Shared Styles ) in Sketch , the names of which corresponded to the names of the tokens of our design system , and then used them to colorize the icons.

Here is an example of how a style is applied to a specific layer:



Here is how styles are declared and then applied to an element: The naming convention plays a



key role . Designers can manage styles in any subfolders: the style name is set by the name of the corresponding token for this color. Thus, subsequently, the build script can programmatically operate them.

Names of pages and artboards used for A / B testing


It's time to understand how to enable designers to conduct A / B testing of icons. Once again, we decided to resort to a naming convention (I am a big fan of the KISS principle).

In this case, we used the names of the pages to determine the test set (using the XP_ prefix ), and the names of the arborboards to determine which resource the A / B test belongs to and which of its variants (indicated in square brackets).



The names and options used for the test were not invented by us - they must match the unique IDs assigned to the tests and options in our own split testing tool. Thus, subsequently, resources can be correctly mapped to a specific user group.

Multiple files for multiple brands


The last thing that interested us was how to maintain different forms of the same icon for different brands?



Compliance with this requirement was very important for our product managers, and we had several options. First, we wanted to use different pages of the same Sketch file, which would be named according to the brand. But they soon realized that this would complicate the life of designers: it would not be easy for them to constantly synchronize the icons of different brands. So we decided to use several files: a common file where all the icons that do not change depending on the brand will be stored, and files for each brand that would replace the “basic” icons from the common file.



Our sketch files are ready! The time has come to write the code.

Read more

Also popular now: