Hero image

Managing Sketch-Files with Git

Real version control for design  — 

Thanks to a new file format introduced last year, Sketch.app produces files that can be put under version control. The new format is based on zipped JSON-files. By putting the unzipped files into version control real diffing and space-saving versioning gets possible.

The problem with version control and design files

Sketch has become very popular with designers in recent years. The reasons are manyfold: it feels lightweight and fast, it stays very close to SVG which has been widely adapted on the web and with all this it is still pretty easy to pick up.

But until recently Sketch had the same problem as most design tools over the years: Design-files are notoriously large and therefore often stored in a binary format. At the same time, the diffing algorithms used in version control systems like Git are very much tailored to human-readable file formats like source code. Therefore a version control system can't use their diffing algorithms to efficiently store changes in a design file. Typically, each new version means a new copy of the design file.

This has two downsides:

  1. Version control of (binary) design files uses a lot of storage
  2. It is hard to see what has changed between two versions of a file because diffing is not possible

A zipped collection of JSON-files

The structure of the .skecth file
The structure of a .sketch-file

The new file format introduced in Sketch 43 (2017) makes it possible to adress these two downsides. A .sketch file is now a zipped collection of (mostly) non-binary files in JSON-format.

The JSON-format is verbose but quite readable. Here is part of the definition of a green circle:

{
    "_class": "oval",
    …
     "points": [
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0.77614237490000004, 1}",
            "curveMode": 2,
            "curveTo": "{0.22385762510000001, 1}",
            "hasCurveFrom": true,
            "hasCurveTo": true,
            "point": "{0.5, 1}"
        },
      …
      ]
     "fills": [
            {
                "_class": "fill",
                "color": {
                    "_class": "color",
                    "alpha": 1,
                    "blue": 0.5272029042243958,
                    "green": 0.9127496480941772,
                    "red": 0.7211930155754089
                },
                "fillType": 0,
                "isEnabled": true,
                "noiseIndex": 0,
                "noiseIntensity": 0,
                "patternFillType": 1,
                "patternTileScale": 1
            }
        ],
        …
}

Version control with Git

To extract the non-binary JSON-files and store them as a version in Git, the following steps are necessary:

  1. Unzip the .sketch-file into a folder
  2. Format the .json-files so that they are human-readable
  3. Remove the preview images because they would just use space
  4. Add everything to git with git add and create a new version with git commit

These steps can be automated with the following script which is an adapted version of the script by Andree Huk:

files='Design01 Design02' # add a new file like this: "file1 file2 file3"
for f in $files
do
  # Copy .sketch to .zip
  cp $f.sketch $f.zip

  # Unzip the file and delete
  unzip -o $f.zip -d $f/
  rm -Rf $f.zip

  for g in $(find $f/ -type f -name '*.json'); do echo $g ; python -m json.tool $g > /tmp/1 && cp /tmp/1 $g ; done
  
  # Remove the preview file
  rm -Rf $f/previews/

  git add $f/
done

# commit with a variable
git commit -m "$1"

Add the .sketch-files to the files-variable on top, save the script e. g. as commit.sh in the folder containing your files and call it like this ./commit.sh "Commit message".

My excitement about this probably also stems from the fact that my Bachelor's thesis included a very similar process for Adobe InDesign-files. But at the time (2014) it was quite a bit more complicated than it is with the new file format of Sketch. Congratulations to the team behind Sketch for this. One more reason, they deserve their success!

Update March 14, 2019

There is even a project which integrate this whole process into Git hooks. So the Git workflow is staying the same but before committing, everything is unzipped, prettified etc. It's in its early stages still but I find the approach very promising.

Update August 12, 2019

The visual diffing functionality of Kactus
The Output of the Kactus Version-Manager for Sketch.

For those who are a bit less at ease with the command line and all these things, there is now a tool called Kactus that will give you a GUI for performing the above steps. For every .sketch file in your repository, it provides the option to "Export Sketch file to JSON" which will do the unzipping and formatting of the JSON-files. It also has a button to do the inverse, namely to "Regenerate Sketch file from JSON". But the best thing about Kactus is that it provides visual diffing:


References: