Skip to main contentSkip to docs navigation

Style Dictionary

The Style Dictionary build of Chassis Tokens, with its commands, build options, platforms, presets, generated files, transforms, filters, and formats.

This page is a work in progress. Parts of it may be incomplete or differ from the current version of Chassis Tokens.

Introduction

Chassis Tokens builds its tokens with Style Dictionary 5 and @tokens-studio/sd-transforms 2. The build reads the token sets that Tokens Studio writes to packages/tokens/source/, and writes SCSS, Swift, Android resources, and Kotlin to packages/tokens/dist/.

This page is the reference of the build for a team that builds its own tokens: how to run and configure the build, which platforms and presets it has, which files it writes, and which transforms, filters, and formats it registers. docs/architecture.md explains why the build works this way and holds the full output contract.

The build, its configuration, and its output are in packages/tokens/, the folder of the published package. Paths on this page that start with source/, build/, dist/, or test/ are relative to that folder.

The generated code on this page shows the format of each platform. Its values are those of the chassis brand in the current version, and differ in other brands.

Build steps

The build runs Style Dictionary once per token-set list, in these steps:

  1. Preprocess: the preprocessor aligns the token types, splits every font weight into a weight and a style, and numbers the tokens in source order.
  2. Transform: the transforms convert names, math, color modifiers, web sizes, and web shadows.
  3. Resolve: Style Dictionary replaces every reference with the value it points to, and stops the build on a reference that points to nothing.
  4. Filter: the filters select the tokens of each file.
  5. Format: the formats print one line per token, in source order, and encode each value for its platform.

Platform values such as UIColor(…), ARGB hex colors, and sizes in dp are encoded in the format step, after the references are resolved. A transform runs before that, and the tokens that reference a token receive its transformed value: the shadow color rgba({color.primitive.neutral.30}, {opacity.context.fg-subtle}) needs a plain color, not a UIColor(…). Add the encoding of a new platform to a format, not to a transform.

Prerequisites

The build runs in a clone of the repository. It needs:

  • Node.js 22 or later
  • pnpm
  • The dependencies of the workspace
  • Token sets in packages/tokens/source/, with the $themes.json that Tokens Studio writes; see Tokens Studio

Clone the repository and install the dependencies:

Shell
git clone https://github.com/chassis-ui/tokens.git chassis-tokens
cd chassis-tokens
pnpm install

To install the tokens package without the dependencies of the documentation site, run pnpm install --filter @chassis-ui/tokens instead. Quick Start covers the setup in more detail.

Run the build

Run the commands of this page from the repository root. Without options, the build writes the files of every brand, theme, app, platform, and screen of the build options:

Shell
pnpm tokens

The files go to dist/<platform>/<app>/<brand>/. The build runs Style Dictionary once per brand, app, and token-set list.

Command line options

The options select a part of the build, change where the build reads and writes, or print information.

OptionEffect
--brand <brands...>Only these brands, such as chassis sinefil
--app <apps...>Only these apps, such as docs demo
--platform <platforms...>Only these platforms, such as web ios android
--theme <themes...>Only the color files of these themes, such as light dark
--screen <screens...>Only the number files of these screens, such as large medium small
--out <dir>Write to another output root instead of dist
--config <file>Read the build options from a JSON file instead of chassis.build
--dry-runList the builds and the files each would write, without building
--help, -hShow the help
--version, -vShow the version

The options from --brand to --screen are filters. Each takes one or more values separated by spaces, and you can combine them:

Shell
pnpm tokens --brand chassis
pnpm tokens --app docs --platform web
pnpm tokens --brand sinefil --platform ios android --screen large small

--theme and --screen limit the color and number files only: every build of a brand, an app, and a platform writes the main and string files. The iOS file Color.swift needs the color files of both themes, so a build with --theme light does not write it.

--config and --out take paths relative to packages/tokens/. The file of --config holds the keys of chassis.build at its top level. This command builds the web-px preset into dist-next/ and leaves dist/ as it is:

Shell
pnpm tokens --config test/golden/web-px.json --out dist-next

Set DEBUG=1 before a command, as in DEBUG=1 pnpm tokens --brand chassis, to print the stack trace of an error.

Dry run

A dry run shows what a set of options or filters selects before you build. It writes nothing.

Shell
pnpm tokens --brand chassis --app docs --dry-run

The build prints each token-set list with the files it writes:

TEXT
  • chassis_docs_light_large
      dist/web/docs/chassis/: main.scss, string.scss, color-light.scss, number-large.scss
  • chassis_docs_dark_large
      dist/web/docs/chassis/: color-dark.scss

The lists of the other screens follow, each with its number file.

Build options

The token system is built on three core groups, brand, theme, and app, and on an optional fourth group, screen. The build options name the options of each group that the build writes, and the platforms of each app. The committed build options are in chassis.build of packages/tokens/package.json:

JSON
"chassis": {
  "build": {
    "brands": ["chassis", "sinefil"],
    "themes": ["light", "dark"],
    "screens": ["large", "medium", "small"],
    "apps": {
      "docs": ["web"],
      "demo": ["ios", "android"]
    }
  }
}
KeyRequiredMeaning
brandsYesOptions of the brand group of source/$themes.json
themesYesOptions of the theme group; the first is the default
appsYesOptions of the app group, each with its platforms
screensNoOptions of the screen group; the first is the default
optionsNoStyle Dictionary options by platform name; see Platform options

The names in the block are the committed configuration, not the system. The build writes only what the keys list, so to build a brand, a theme, or an app of your own, add its name to the key of its group and give it token sets in source/$themes.json.

To build without screens, set screens to [] or leave the key out, and remove the screen group from source/$themes.json. The build then writes one number file with no screen in its name: number.scss on the web, Number.swift on iOS, and number.xml with res/values/number.xml on Android.

Token-set lists

A token-set list is the list of token sets that one run of Style Dictionary reads. The build combines one option of each group of source/$themes.json into a list named <brand>_<app>_<theme>_<screen>, or <brand>_<app>_<theme> without screens. chassis_docs_light_large is a list of the committed configuration. Every name in the build options must be an option of its group.

The files of a brand and an app that need the same token sets share one list:

Token-set listFiles
First theme, first screenThe main file, the string file, the color file of the first theme, the number file of the first screen
Each other theme, first screenThe color file of the theme
First theme, each other screenThe number file of the screen

A list holds its token sets in the order of source/$themes.json, so a later token set overrides an earlier one, as in Tokens Studio. Style Dictionary reports these overrides as token collisions in every build; they are expected.

Chassis Tokens is meant to be owned and customized, so you can add a group of your own. A new group adds a segment to the name of every token-set list. planBuilds in packages/tokens/build/build.js makes that name from the brand, the app, the theme, and the screen, and decides which files each list writes, so a new group needs a change there.

Platform options

The options key holds Style Dictionary options by platform name. The build merges them into the options of that platform, and fails when options names a platform that no app uses.

OptionPlatformsEffect
outputReferencesEvery platform except webPrints the name of the referenced token instead of the value; see References
packageNameandroid-composeThe package of the Kotlin files, chassis.tokens by default
screensandroidThe resource qualifier of each screen

options.android.screens maps each screen to the qualifier of its folder in the res/ tree, with "" for the default values folder. Every screen needs a qualifier, and exactly one screen goes into the default folder. Without the option, small goes into values, medium into values-sw600dp, and large into values-sw840dp.

Platforms

A platform is a build target that an app selects in chassis.build.apps. The committed build options use web, ios, and android, which write the published package; the other platforms are presets.

PlatformFormatOutput folderOutput
webcx/scss-chassis-cssdist/web/<app>/<brand>/SCSS variables for Chassis CSS, sizes in rem
web-scsscx/scss-variablesdist/web/<app>/<brand>/SCSS variables with resolved values, sizes in rem
web-pxcx/scss-variablesdist/web/<app>/<brand>/The same, sizes in px
web-vwcx/scss-variablesdist/web/<app>/<brand>/The same, sizes in vw
ioscx/ios-swift-classdist/ios/<app>/<brand>/Swift constants for UIKit, Color.swift, and Icons.xcassets
ios-swiftuicx/swiftuidist/ios-swiftui/<app>/<brand>/Swift constants with SwiftUI values
androidcx/android-resourcesdist/android/<app>/<brand>/XML resources, as flat files and as a res/ tree with drawables
android-composecx/compose-objectdist/android-compose/<app>/<brand>/Kotlin objects for Jetpack Compose

Each platform has its own name and format for a token. space.context.medium, which references {size.unit.16}, prints as:

PlatformNameFormat
web, web-scss$cx-space-context-mediumA size in rem
web-px$cx-space-context-mediumA size in px
web-vw$cx-space-context-mediumA size in vw
ios, ios-swiftuiSpaceContextMediumA CGFloat in points
android@dimen/space_context_mediumA <dimen> in dp
android-composespaceContextMediumA size with .dp

The formats hold the value rules of each platform. The guides for web, iOS, and Android show how to use the files in an app.

Presets

A preset is a platform for a team that owns its tokens and does not use Chassis CSS, UIKit, or Android resources. Select a preset by its name in chassis.build.apps. The committed dist/ holds no preset output; the output of each preset for the chassis brand is in test/golden/.

Presets for other CSS frameworks

The web platform prints the custom properties of Chassis CSS, such as var(--default-fg-main), so its SCSS works only with Chassis CSS. The presets web-scss, web-px, and web-vw print resolved values in the unit of their name. In chassis.build of packages/tokens/package.json:

JSON
"apps": {
  "docs": ["web-px"]
}

The build then writes every value resolved, with sizes in pixels; cx/scss-variables shows the format. The web platforms write the same file names to the same folder, dist/web/<app>/<brand>/, so give an app one of them. Line heights and letter spacing are in em in every unit.

Each preset is a file of packages/tokens/build/config/ that calls webConfig({ unit, format }) of web.js. You can edit these files as any other platform file.

SwiftUI and Compose presets

The presets ios-swiftui and android-compose write the tokens for apps that use SwiftUI or Jetpack Compose. Select them next to, or instead of, ios and android. In chassis.build of packages/tokens/package.json:

JSON
"apps": { "demo": ["ios-swiftui", "android-compose"] },
"options": { "android-compose": { "packageName": "com.example.tokens" } }
PresetFilesDifferences
ios-swiftuiThe Swift files of ios, with the same typesColor and Font.Weight values; no Color.swift, no Icons.xcassets, no …Radius constants
android-composeOne Kotlin object per file: ChassisTokens.kt, String.kt, ColorLight.kt, NumberLarge.kt, …Compose values with camelCase names; no res/ tree, no drawables

Each file of these presets holds one theme or one screen. For colors that follow the appearance in SwiftUI, build the ios platform too and wrap its ChassisTokensColor constants in Color(uiColor:). See cx/swiftui and cx/compose-object for the values.

Generated files

Every platform writes a main file, a string file, one color file per theme, and one number file per screen.

PlatformFiles
Webmain.scss, string.scss, color-<theme>.scss, number-<screen>.scss
iOSChassisTokens.swift, String.swift, Color<Theme>.swift, Number<Screen>.swift, Color.swift, Icons.xcassets
Androidmain.xml, string.xml, color_<theme>.xml, number_<screen>.xml, and the res/ tree

Color files use the token sets of their theme, and number files the token sets of their screen. The main and string files use the token sets of the first theme and the first screen of the build options.

The main file holds every token except the theme colors, which are color.primitive.*, color.context.*, and the gradients. Its component colors are the ones of the first theme, and its numbers the ones of the first screen. The string, color, and number files share no names with each other, and together they hold everything in the main file except the base colors.

On iOS, each file declares a caseless public enum, so all files fit in one module: ChassisTokens in ChassisTokens.swift, and ChassisTokens<File> in the others, such as ChassisTokensColorLight. When the themes include light and dark, the build writes Color.swift after the other files. Its type ChassisTokensColor holds the colors of both themes:

SWIFT
    public static let ColorContextDefaultFgMain = UIColor { $0.userInterfaceStyle == .dark ? UIColor(red: 0.914, green: 0.925, blue: 0.929, alpha: 1) : UIColor(red: 0.086, green: 0.102, blue: 0.106, alpha: 1) }

Package.swift at the repository root declares one Swift library per brand of every app with an iOS platform. Run pnpm tokens:swift-package after you change the brands or apps.

On Android, the res/ tree holds the same resources as the flat files, in the folders that Android selects by itself:

FolderFiles
res/values/string.xml, color_base.xml, color.xml of the first theme, number.xml of the screen with the qualifier ""
res/values-night/color.xml of the dark theme
res/values-<qualifier>/number.xml of each other screen
res/drawable/One vector drawable per icon

main.xml cannot share a resource folder with the flat string, color, or number files: aapt2 fails with has a conflicting value. Add either main.xml or the flat files to a module. The res/ tree needs neither.

An icon is an asset token whose value is an SVG document, such as icon.accordion.indicator. It stays a string on every platform. The ios platform also writes it to Icons.xcassets/IconAccordionIndicator.imageset/, and the android platform to res/drawable/icon_accordion_indicator.xml.

References

By default every token prints its resolved value. With outputReferences, a token that references another token prints the name of that token, wherever the result compiles and keeps the value. The web platform ignores the option: it prints the custom properties of Chassis CSS in every build.

Set the option per platform. In chassis.build of packages/tokens/package.json:

JSON
"apps": { "docs": ["web-px"], "demo": ["ios", "android"] },
"options": {
  "web-px": { "outputReferences": true },
  "ios": { "outputReferences": true }
}
PlatformPrintsExample
web-scss, web-px, web-vwThe SCSS variable$cx-color-context-default-fg-main
ios, ios-swiftuiThe constantDimensionBase4
androidThe resource reference@dimen/dimension_base_4
android-composeThe propertydimensionBase4

In SCSS, a color, space, opacity, border radius, or border width token prints a variable when the Chassis CSS format prints a custom property for it. Typography maps name the variables of their family, weight, size, line height, and style. Shadows print their value. The web-px preset writes:

SCSS
$cx-border-radius-accordion-main: $cx-border-radius-context-medium !default;
$cx-border-width-accordion-main: $cx-border-width-context-medium !default;

With outputReferences, load color-light.scss or color-dark.scss before main.scss. The component colors of main.scss name context colors, which only the color files declare.

On iOS and Android, a token names the token it references only when that token is in the same file and encodes to the same text, and on Android to the same kind of resource. Base colors and sizes computed with math print their values. The ios platform writes in ChassisTokens.swift:

SWIFT
    public static let SizeUnit4 = DimensionBase4
    public static let SizeDatepickerWeekWidth = CGFloat(224)
    public static let SpaceContextMedium = SizeUnit16
    public static let BorderRadiusAccordionMain = BorderRadiusContextMedium

SizeDatepickerWeekWidth is {size.datepicker.day-width}*7, so it prints its value. ColorAccordionItemFgColor prints its value in ChassisTokens.swift too, because the context colors are in the color files; in ColorLight.swift it is ColorContextDefaultFgMain. The android platform writes in main.xml:

XML
  <dimen name="size_unit_4">@dimen/dimension_base_4</dimen>
  <dimen name="space_context_medium">@dimen/size_unit_16</dimen>
  <dimen name="font_context_jumbo_font_size">96sp</dimen>

The font size prints its value because it is in sp, and the size it references, size_unit_96, is in dp.

Check the output

These commands check the token source and the output of the build. Run the source lint before you build, and the other two after.

Lint the source

The source lint finds mistakes that the build accepts. It reads the token sets that source/$themes.json selects:

Shell
pnpm tokens:lint:source

The lint fails, and names the token set and the token, when:

  • the options of the theme or screen group declare different names in their token sets
  • a name has characters other than letters, digits, and single hyphens, starts with a digit, or becomes the same SCSS, Swift, Android, or Compose name as another token
  • a font weight is not one the build knows
  • a token has no $type, or a value is not a token
  • two token sets of one token-set list declare the same name with different types

Verify the output

The golden check compares a fresh build with the committed dist/. It builds into dist-next/ and never writes to dist/:

Shell
pnpm tokens:verify

The check ignores the timestamp and version lines of the file headers. It also fails when a name appears twice in one file, and when a reference names nothing that the output declares. Add --platform ios to build and check one platform. After you change tokens or build options, run pnpm tokens and commit the updated dist/.

Token diff report

The diff report lists what a change does to the tokens of each file: the names added, removed, renamed, and changed in value. It marks removed and renamed names as breaking.

Shell
pnpm tokens:diff

The report compares the working dist/ with the dist/ of main. Add --base with a branch, a tag, or a commit, as in pnpm tokens:diff --base v0.5.3, to compare with another one.

Preprocessor

The preprocessor cx/global prepares the tokens of every build before the transforms run. It changes the tokens in these ways:

  • It aligns the types of Tokens Studio with the types of Style Dictionary, with alignTypes of @tokens-studio/sd-transforms: fontWeights becomes fontWeight.
  • It types letter spacing tokens as number, so the size transforms leave them alone.
  • It splits every font weight token into a weight and a style token. typography.fontWeight.html.blockquote names a weight and a style, and becomes typography.fontWeight.html.blockquote.weight and typography.fontWeight.html.blockquote.style. A weight that names no style gets the style normal.
  • It numbers the tokens in source order. The formats sort by this number, so the parts of a typography or shadow token stand where the token is in the source.

Transforms

Transforms run before the references are resolved. Each platform lists its transforms in its file of packages/tokens/build/config/; no platform uses a transform group.

TransformPlatformsEffect
name/kebabWeb platformsNames in the form space-context-medium
name/pascalios, ios-swiftuiNames in the form SpaceContextMedium
name/snakeandroidNames in the form space_context_medium
name/camelandroid-composeNames in the form spaceContextMedium
ts/resolveMathAllComputes a value with math, such as {size.datepicker.day-width}*7
ts/color/modifiersAllApplies the color modifiers of Tokens Studio
ts/color/css/hexrgbaAllTurns a color with an alpha, such as rgba({color.primitive.neutral.30}, {opacity.context.fg-subtle}), into a CSS rgba() color
ts/typography/fontWeightWeb platformsTurns the name of a font weight into its number

The name transforms come from Style Dictionary and the ts/ transforms from @tokens-studio/sd-transforms. The build registers the cx/ transforms in packages/tokens/build/transforms.js, all for the web platforms:

TransformPlatformsTokensEffect
cx/size/remweb, web-scssSizesDivides the design pixels by basePxFontSize and adds rem
cx/size/pxweb-pxSizesAdds px to the design pixels
cx/size/vwweb-vwSizesDivides the design pixels by basePxFontSize and adds vw
cx/shadow/webWeb platformsShadowsJoins the parts of each layer into a CSS box-shadow

Sizes are the tokens typed dimension, fontSize, lineHeight, or paragraphSpacing. basePxFontSize is an option of the platform, which packages/tokens/build/config/web.js sets to 16. dimension.base.05 holds half a design pixel, and size.unit.05 references it. With cx/size/rem, the build writes in main.scss:

SCSS
$cx-dimension-base-05: 0.03125rem !default;
$cx-size-unit-05: 0.03125rem !default;

No size is rounded. The web platforms set mathFractionDigits to 10, so ts/resolveMath keeps the value of a size that references another size.

cx/shadow/web prints each layer of a shadow as its horizontal offset, vertical offset, blur, spread, and color, with inset after an inner shadow, and joins the layers with commas. The build writes in main.scss:

SCSS
$cx-shadow-context-inset: 0rem 0.125rem 0.25rem 0rem rgba(0, 0, 0, 0.1) inset !default;

Filters

A filter selects the tokens of one kind of file by their type and path. Every platform uses the same filters, so a token is in the same kind of file on every platform.

FilterFilesTokensExample
cx/allTokensMainEvery type that the build writes, without the colors under color.primitive, color.context, color.utility, and gradient.primitivecolor.accordion.item-fg-color
cx/stringTokensStringasset, content, fontFamily, fontStyle, fontWeight, string, text, textCase, textDecoration, typeicon.accordion.indicator
cx/themeTokensColorColors whose second path segment is not base or utility, and shadowscolor.context.default.fg-main
cx/numberTokensNumberduration, letterSpacing, number, opacity, and the sizesspace.context.medium
cx/baseColorTokensres/values/color_base.xml of AndroidColors whose second path segment is basecolor.base.context.light.default.fg-main

Gradients are typed color, so gradient.primitive.* is in the color files and not in the main file. Only the web keeps a shadow whole, so only the web color files hold shadows; iOS and Android split a shadow into parts, and the color of each layer is in the main file and the color files. No file holds the tokens typed boolean or other, the colors under color.utility, or the groups that exist for Figma only, figma.* and bg-blur.*.

Formats

A format prints one kind of file. Every format starts a file with a header that holds the build time, the version of the package, and the license, and prints the tokens in source order.

cx/scss-chassis-css

This format prints SCSS variables for Chassis CSS, and the web platform uses it. Each token is one $cx-<name>: <value> !default; line. The build writes in main.scss:

SCSS
$cx-space-context-medium: 1rem !default;
$cx-color-accordion-item-fg-color: var(--default-fg-main) !default;
$cx-typography-line-height-text-medium: 1.5em !default;
$cx-border-radius-accordion-main: var(--border-radius-md) !default;
$cx-font-context-lead: ("font-family": var(--font-family-text), "font-weight": var(--font-weight-text-normal), "font-size": var(--font-size-text-xl), "line-height": var(--line-height-text-xl), "font-style": normal, "letter-spacing": 0em, "margin-bottom": 0rem, "text-transform": none, "text-decoration": none) !default;

A token prints var(--<name>) when its value is a single reference to a token that Chassis CSS has a custom property for: color.context.*, color.primitive.*, space.context.*, opacity.context.*, opacity.level.*, shadow.context.*, borderRadius.context.*, or borderWidth.context.*. The name follows the referenced path, with the scale steps shortened as in Chassis CSS: medium becomes md, and xlarge becomes xl. Every other token prints its value:

  • Sizes are in rem.
  • Colors are hex, or rgba() when they have an alpha.
  • A line height token is divided by the font size token of the same step, and printed in em.
  • Letter spacing is in em: the design pixels divided by basePxFontSize.
  • Font weights are numbers, font families keep their whole list, and assets are in double quotes.
  • A typography token is a Sass map, with a custom property for its family, weight, size, and line height.

cx/scss-variables

This format prints SCSS variables for other CSS frameworks, and the presets web-scss, web-px, and web-vw use it. It prints the file of cx/scss-chassis-css with every value resolved. The web-scss preset writes in main.scss:

SCSS
$cx-space-context-medium: 1rem !default;
$cx-color-accordion-item-fg-color: #161a1b !default;
$cx-border-radius-accordion-main: 0.375rem !default;

The Sass map of a typography token holds resolved values too, and quotes the list of font families as one string. With outputReferences, the format prints SCSS variables; see References.

cx/ios-swift-class

This format prints one Swift type with a public static let per token, and the ios platform uses it. The build writes in ChassisTokens.swift:

SWIFT
import UIKit

public enum ChassisTokens {
    public static let SpaceContextMedium = CGFloat(16)
    public static let ColorButtonPrimaryBgIdle = UIColor(red: 0.000, green: 0.643, blue: 0.800, alpha: 1)
    public static let FontContextJumboLineHeight = CGFloat(120)
    public static let FontContextJumboFontSize = CGFloat(96)
    public static let FontContextJumboLetterSpacing = CGFloat(-0.5)
    public static let ShadowContextSmall1Blur = CGFloat(8)
    public static let ShadowContextSmall1Radius = CGFloat(4)
}
  • Colors are UIColor with three decimals per channel. Numbers and sizes are CGFloat, in points.
  • A font family is a string with the first family of the list. A font weight is a UIFont.Weight constant.
  • A typography or shadow token becomes one constant per part. A line height in percent prints in points, as that share of the font size of its token.
  • After the blur of each shadow layer, a …Radius constant holds half the blur, for the shadowRadius of Core Animation.
  • A gradient becomes an angle, and a color and a position per stop: GradientPrimitiveBlackL000Angle, GradientPrimitiveBlackL000Stop1Color, GradientPrimitiveBlackL000Stop1Position. The format reads linear-gradient() with a direction in deg, or to top, to right, to bottom, or to left.

cx/swiftui

This format prints the Swift files with SwiftUI values, and the ios-swiftui preset uses it. Colors are Color and font weights Font.Weight; every other value is the one of cx/ios-swift-class, without the …Radius constants. The preset writes in ColorLight.swift:

SWIFT
import SwiftUI

public enum ChassisTokensColorLight {
    public static let ColorContextDefaultFgMain = Color(red: 0.086, green: 0.102, blue: 0.106, opacity: 1)
}

cx/android-resources

This format prints a <resources> file with one element per token, and the android platform uses it. The build writes in main.xml:

XML
<resources>
  <dimen name="space_context_medium">16dp</dimen>
  <item name="opacity_level_10" type="dimen" format="float">0.1</item>
  <color name="color_button_primary_bg_idle">#ff00a4cc</color>
  <dimen name="font_context_jumbo_line_height">120sp</dimen>
  <dimen name="font_context_jumbo_font_size">96sp</dimen>
  <item name="font_context_jumbo_letter_spacing" type="dimen" format="float">-0.0052</item>
</resources>

The type of a token decides its element:

TokensElementFormat
Opacity, letter spacing, gradient angles and positions<item type="dimen" format="float">A number
Font weights<integer>A weight number
Colors<color>ARGB hex
Sizes<dimen>A size in dp or sp
Everything else<string>Text, escaped for Android

Font sizes, line heights, and paragraph spacing are in sp, and other sizes in dp. The letter spacing of a typography token is in ems of its font size, which android:letterSpacing takes. Typography, shadow, and gradient tokens become parts as on iOS, without the …Radius constants.

cx/compose-object

This format prints one Kotlin object per file with a getter per token, and the android-compose preset uses it. The values are the ones of cx/android-resources as Compose types. The preset writes in NumberLarge.kt:

KOTLIN
package chassis.tokens

object ChassisTokensNumberLarge {
    val spaceContextMedium get() = 16.dp
    val opacityLevel40 get() = 0.4f
    val fontContextJumboLetterSpacing get() = (-0.0052).em
    val fontContextLeadFontSize get() = 22.sp
}

Colors are Color(0xAARRGGBB), font weights are FontWeight with the weight number, and strings are Kotlin string literals. Every property is a getter, because with outputReferences a property may name one that the file declares later.

Troubleshooting

The build prints the message of an error after Build failed, or after Failed: and the name of the token-set list. Run it with DEBUG=1 for the stack trace.

Unknown platform

The build stops with Unknown platform: web-rem. An app of chassis.build.apps lists a platform that the build does not have. Use one of the names of the platforms table.

Unknown filter value

The build stops with Unknown filter values: --brand chasis (configured: chassis, sinefil). A filter of the command names a brand, app, platform, theme, or screen that chassis.build does not have. Use one of the configured values. The build also stops with The filters select no build when the filters together select nothing, such as --app docs --platform ios while the docs app has only the web platform.

No token sets

The build stops with No token sets for acme_docs_light_large in source/$themes.json. A brand, app, theme, or screen of the build options is not an option of its group in source/$themes.json, or the build options have no screens and source/$themes.json has a screen group. Check the spelling of the name, or add the option in Tokens Studio.

Unused platform options

The build stops with Invalid package.json: options for platforms no app uses: web-px. chassis.build.options has a key that is not a platform of any app. Add the platform to an app, or rename the key to the platform that the app uses.

Android screen folders

The build stops with no Android resource qualifier for the screens large; set them in options.android.screens, or with options.android.screens must put exactly one screen in the default folder ("") but puts 0. The defaults cover the screens small, medium, and large, and options.android.screens replaces them as a whole. Give every screen of chassis.build.screens a qualifier in options.android.screens, and give exactly one screen the qualifier "".

Broken reference

A build fails with Some token references (1) could not be found. A token references a token that is not in the token sets of the list, because of a misspelled path or a token set that the option of source/$themes.json does not select. To list the references, add verbosity: 'verbose' to log in packages/tokens/build/config/index.js and build again.

Undeclared SCSS variable

A build with outputReferences fails with No file declares a variable for, followed by the path of a token. A token references a token that no file holds, such as a token typed boolean or other. Give the referenced token a type that the build writes, or build the platform without outputReferences.

Unknown font weight

A build of an iOS or Android platform fails with Unknown font weight "Extra Heavy" in typography.fontWeight.text.strong.weight. The build knows the weight names of ts/typography/fontWeight, and ignores case, spaces, and hyphens in them. Use one of these names in the token; pnpm tokens:lint:source finds the token before the build.

Golden check failed

pnpm tokens:verify prints Golden check failed against dist/ and the first differing lines of each file. The committed dist/ is older than the tokens or the build options. Run pnpm tokens, review the changes with pnpm tokens:diff, and commit dist/.

Next steps

The build is one part of the token workflow. Continue with the part you need: