Skip to main contentSkip to docs navigation

Design Guidelines

Where a designer puts an exported file, how to name it, which formats each platform gets, and how the change reaches the repository.

Introduction

This page is for the designer who exports a file and adds it to the repository. It covers the folder a file goes to, the name it gets, the formats each platform keeps, and the commit that brings it in.

You work in source/ only. The build writes the names, the formats and the folders of each platform from what you put there, and nothing under dist/ is edited by hand.

Prerequisites

You need Git and Git LFS. Fonts and raster images are Git LFS files: run git lfs install once on your machine before you clone, so that you get the files and not their pointers. A Git client with a window, such as GitHub Desktop, works as well as the command line.

To build the output and look at it before you commit, you also need Node.js and pnpm, see the quick start.

Source layout

Every file has a brand, an app and a type, and its path says all three.

TEXT
source/
├── default/          -> the default brand: files that every brand gets
│   └── <app>/        -> one folder per app
│       └── <type>/   -> fonts, images, icons, or any other folder
└── <brand>/          -> one folder per brand: only the files that differ
    └── <app>/
        └── <type>/

The brands and the apps are those of the chassis block of package.json. A folder that the configuration does not name is not read by the build, and the source lint warns about it.

Overrides

A brand file replaces the default file of the same path. For each brand, the build takes the files of source/default/<app>/ first and then the files of source/<brand>/<app>/ over them.

Add a file to a brand only when it differs from the default one. A logo that every brand shares belongs in source/default/, once, and a brand with a logo of its own adds a file with the same subfolder and the same name to its folder.

Naming

A name in source/ is made of lowercase letters, digits and hyphens, with a lowercase extension. Each platform renames the file from there: the web keeps the hyphens, iOS and Android get underscores.

  • Separate words with hyphens: hero-background.jpg.
  • Name a file after what it shows or does: illustration-onboarding.svg, not image1.svg.
  • Put the color mode at the end of the name: comp-gallery-light.png and comp-gallery-dark.png.
  • End a variant with its indicator: hero-image.png, hero-image@2x.png, hero-image@3x.png.
  • Do not use spaces, capitals or underscores: Hero Background.jpg and hero_background.jpg fail the source lint.
  • Do not put a dot or an indicator inside a name: hero.v2.png and hero@2x-final.png fail the source lint.
  • Do not put the brand in the name: the folder says it, and a brand file has to have the name of the default file to replace it.

The source lint checks these rules on every pull request. Run it yourself with pnpm assets:lint:source.

Formats

Export the formats of the platforms that the app is built for. The build leaves a format out where the platform does not use it, and does not convert one into another.

Fonts

Fonts go to fonts/, named by role, with their license beside them.

PlatformGetsDoes not get
WebWOFF2, WOFF, and the stylesheets of the folderTTF, OTF
iOSTTF, OTFWOFF2, WOFF, stylesheets
AndroidTTF, OTFWOFF2, WOFF, stylesheets

See fonts for the role names and the license files.

Images

Images go to images/, in any subfolders, with the variants an app needs.

PlatformGetsDoes not get
WebEvery format
iOSEvery format but WebP, with the indicator in the nameWebP
AndroidEvery format, in density folders

See images for the variants and the density folders.

Icons

Icons go to icons/ as the build output of Chassis Icons. You do not export them into this repository one by one.

PlatformGetsDoes not get
WebEvery file
iOSSVG, PDF, PNGThe icon font and its stylesheets
AndroidSVG, with the ic_ prefixEvery other format

See icons for how the copy is refreshed.

Other files

Any other folder under an app, such as videos/ or data/, is copied to every platform in every format. See other assets.

Adding a file

A change to the assets is a commit on a branch, reviewed in a pull request against develop.

  1. Create a branch from develop.
  2. Export the file from the design tool into its folder under source/.
  3. Run pnpm assets:lint:source to check the name, and pnpm assets to see the file in dist/.
  4. Add a changeset with pnpm changeset. It names the files that the change adds to dist/, removes from it or renames.
  5. Commit the files of source/ and the changeset, and open a pull request against develop.
Shell
git checkout -b feature/onboarding-assets develop
pnpm assets:lint:source
pnpm assets
pnpm changeset
git add source/default/docs/images/onboarding.svg .changeset
git commit -m "feat: add the onboarding illustration"
git push origin feature/onboarding-assets

dist/ is not committed. Every consumer builds it from the source.

Best practices

These practices keep source/ to the files the build is meant to copy, and a commit to one change.

  • Check the license before adding a font or a stock image: a font keeps its license beside it as text-license.txt, display-license.txt or code-license.txt.
  • Export every variant an app needs: the build copies @2x and @3x files and does not make them.
  • Commit the exported file only: design sources, such as a .fig or a .sketch file, do not belong in source/. Every file of a type folder is copied to the output.
  • Stage only the files of the change: a commit with unrelated exports is hard to review and to revert.

Avoid the habits that undo this:

  • Do not copy a default file into a brand folder unchanged: the brand gets the default file anyway, and the copy has to be kept in step by hand.
  • Do not edit the icon folders by hand: icons/icons/ and icons/svgs/ are replaced by the next copy from Chassis Icons.

Next steps

Continue with one of these pages: