Skip to content

Configuration

Style dictionaries are configuration driven. Your configuration lets Style Dictionary know:

  1. Where to find your design tokens
  2. How to transform and format them to generate output files

Here is an example configuration:

config.json
{
"source": ["tokens/**/*.json"],
"platforms": {
"scss": {
"transformGroup": "scss",
"prefix": "sd",
"buildPath": "build/scss/",
"files": [
{
"destination": "_variables.scss",
"format": "scss/variables"
}
],
"actions": ["copy_assets"]
},
"android": {
"transforms": ["attribute/cti", "name/snake", "color/hex", "size/remToSp", "size/remToDp"],
"buildPath": "build/android/src/main/res/values/",
"files": [
{
"destination": "style_dictionary_colors.xml",
"format": "android/colors"
}
]
}
}
}

Configuration file formats

Style Dictionary supports configuration files in these file formats:

  • JSON
  • JSONC
  • JSON5
  • Javascript (ES Modules, default export)

Here is an example using an ES module for configuration:

config.js
export default {
source: [`tokens/**/*.json`],
// If you don't want to call the registerTransform method a bunch of times
// you can override the whole transform object directly. This works because
// the .extend method copies everything in the config
// to itself, allowing you to override things. It's also doing a deep merge
// to protect from accidentally overriding nested attributes.
transform: {
// Now we can use the transform 'myTransform' below
myTransform: {
type: 'name',
transform: (token) => token.path.join('_').toUpperCase(),
},
},
// Same with formats, you can now write them directly to this config
// object. The name of the format is the key.
format: {
myFormat: ({ dictionary, platform }) => {
return dictionary.allTokens.map((token) => `${token.name}: ${token.value};`).join('\n');
},
},
platforms: {
// ...
},
};

Some interesting things you can do in a JS file that you cannot do in a JSON file:

  • Add custom transforms, formats, filters, actions, preprocessors and parsers
  • Programmatically generate your configuration

Using configuration files

By default, the Style Dictionary CLI looks for a config.json or config.js file in the root of your package.

package.json
"scripts": {
"build": "style-dictionary build"
}

You can also specify a custom location when you use the CLI with the --config parameter.

package.json
"scripts": {
"build": "style-dictionary build --config ./sd.config.js"
}

Using in Node

You can also use Style Dictionary as an npm module and further customize how Style Dictionary is run, for example running Style Dictionary multiple times with different configurations. To do this you would create a Javascript file that imports the Style Dictionary npm module and calls the .extend and .buildAllPlatforms functions.

build-tokens.js
import StyleDictionary from 'style-dictionary';
const myStyleDictionary = new StyleDictionary({
// configuration
});
await myStyleDictionary.buildAllPlatforms();
// You can also extend Style Dictionary multiple times:
const myOtherStyleDictionary = await myStyleDictionary.extend({
// new configuration
});
await myOtherStyleDictionary.buildAllPlatforms();

You would then change your npm script or CLI command to run that file with Node:

package.json
"scripts": {
"build": "node build-tokens.js"
}

Properties

PropertyTypeDescription
logLogConfigure logging behavior to either reduce/silence logs or to make them more verbose for debugging purposes.
sourcestring[]An array of file path globs to design token files. Style Dictionary will do a deep merge of all of the token files, allowing you to organize your files however you want.
includestring[]An array of file path globs to design token files that contain default styles. Style Dictionary uses this as a base collection of design tokens. The tokens found using the “source” attribute will overwrite tokens found using include.
tokensObjectThe tokens object is a way to include inline design tokens as opposed to using the source and include arrays.
expandExpandConfigConfigures whether and how composite (object-value) tokens will be expanded into separate tokens. false by default. Supports either boolean, ExpandFilter function or an Object containing a typesMap property and optionally an include OR exclude property.
platformsRecord<string, Platform>An object containing platform config objects that describe how the Style Dictionary should build for that platform. You can add any arbitrary attributes on this object that will get passed to formats and actions (more on these in a bit). This is useful for things like build paths, name prefixes, variable names, etc.
hooksHooks objectObject that contains all configured custom hooks: preprocessors. Note: parsers, transforms, transformGroups, formats, fileHeaders, filters, actions will be moved under property this later. Can be used to define hooks inline as an alternative to using register<Hook> methods.
parsersstring[]Names of custom file parsers to run on input files
preprocessorsstring[]Which preprocessors (by name) to run on the full token dictionary, before any transforms run, can be registered using .registerPreprocessor. You can also configure this on the platform config level if you need to run it on the dictionary only for specific platforms.
transformRecord<string, Transform>Custom transforms you can include inline rather than using .registerTransform. The keys in this object will be the transform’s name, the value should be an object with type
formatRecord<string, Format>Custom formats you can include inline in the configuration rather than using .registerFormat. The keys in this object will be for format’s name and value should be the format function.
usesDtcgbooleanWhether the tokens are using DTCG Format or not. Usually you won’t need to configure this, as style-dictionary will auto-detect this format.

Log

Log configuration object to configure the logging behavior of Style Dictionary.

Platform

A platform is a build target that tells Style Dictionary how to properly transform and format your design tokens for output to a specific platform. You can have as many platforms as you need and you can name them anything, there are no restrictions.

PropertyTypeDescription
transformsstring[]An array of transform keys to be performed on the design tokens. These will transform the tokens in a non-destructive way, allowing each platform to transform the tokens. Transforms to apply sequentially to all tokens. Can be a built-in one or you can create your own.
transformGroupstringA string that maps to an array of transforms. This makes it easier to reference transforms by grouping them together. Can be combined with transforms.
buildPathstringBase path to build the files, must end with a trailing slash.
expandExpandConfigConfigures whether and how composite (object-value) tokens will be expanded into separate tokens. false by default. Supports either boolean, ExpandFilter function or an Object containing a typesMap property and optionally an include OR exclude property.
preprocessorsstring[]Which preprocessors (by name) to run on the full token dictionary when building for this particular platform, before any transforms run, can be registered using .registerPreprocessor. You can also configure this on the global config.
optionsObjectOptions that apply to all files in the platform, for example outputReferences and showFileHeader
prefixstringA string that prefix the name of the design tokens.
filesFile[]Files to be generated for this platform.
actionsstring[]Actions to be performed after the files are built for that platform. Actions can be any arbitrary code you want to run like copying files, generating assets, etc. You can use pre-defined actions or create custom actions.

File

A File configuration object represents a single output file. The options object on the file configuration will take precedence over the options object defined at the platform level. Apart from the options listed below, any other options can be added, which can then be used inside custom formats.

PropertyTypeDescription
destinationstringLocation to build the file, will be appended to the buildPath.
formatstringFormat used to generate the file. Can be a built-in one or you can create your own via registerFormat.
filterstring | function | ObjectA function, string or object used to filter the tokens that will be included in the file. If a function is provided, each design token will be passed to the function and the result (true or false) will determine whether the design token is included. If an object is provided, each design token will be matched against the object using a partial deep comparison. If a match is found, the design token is included. If a string is passed, is considered a custom filter registered via registerFilter
optionsObjectA set of extra options associated with the file. Includes showFileHeader and outputReferences.
options.showFileHeaderbooleanIf the generated file should have a comment at the top about being generated. The default fileHeader comment has “Do not edit + Timestamp”. By default is “true”.
options.fileHeaderstring |functionA custom fileHeader that can be either a name of a registered file header (string) or an inline fileHeader function.
options.outputReferencesboolean | OutputReferencesFunctionIf the file should keep token references. By default this is “false”. Also allows passing a function to conditionally output references on a per token basis.

Expand

You can configure whether and how composite (object-value) tokens will be expanded into separate tokens. By default, this functionality is disabled and for formats such as CSS where object values are not supported, you’d be relying on either a custom value transform to turn such token values into strings, or writing a custom format to format object values into CSS compatible values.

Expand usage

Below are examples of how the expand property can be used.

{
expand: true, // expand all object-value (composite) type tokens
expand: {}, // equivalent to true
// conditionally expand, executes this callback for each individual token
expand: (token, config, platformConfig) => true,
// equivalent to true, but additionally passing a typesMap
expand: {
typesMap: {
width: 'dimension',
},
},
// only expands typography and border tokens, also passes a typesMap
expand: {
include: ['typography', 'border'],
// more info about typesMap later...
typesMap: {
// all width props are mapped to 'dimension' type
width: 'dimension',
typography: {
// fontSize prop is mapped to 'dimension' type if inside a typography composite type token
fontSize: 'dimension',
},
},
},
// expands everything except for typography and border tokens
expand: {
exclude: ['typography', 'border'],
},
// only expands tokens for which this function returns true
expand: {
include: (token, config, platformConfig) => true,
},
// expands everything except for tokens for which this function returns true
expand: {
exclude: (token, config, platformConfig) => true,
},
}

The value of expand can be multiple things:

  • boolean, false by default, when set to true, any object-value (composite) design token will be expanded into multiple tokens, one for each property.
  • a function of type ExpandFilter, e.g. (token, options, platform) => true, must return a boolean, when true will expand that individual token, arguments:
    • token: the design token of which the value is an object (composite)
    • options: the StyleDictionary config options
    • platform: this is only passed when expand is used on the platform level, contains the platform specific config options
  • An object:
    • Empty, which is equivalent of passing true
    • Containing just a typesMap, which is also equivalent of passing true, except you’re also passing the typesMap
    • Also containing an include or exclude property which can be either an array of composite types or an ExpandFilter function, to conditionally expand or negate expand of individual tokens

Global vs Platform

You can enable the expanding of tokens both on a global level and on a platform level.

Whether configured on platform or global level, the token expansion will happen immediately after user-configured preprocessors and before transform hooks.
That said, platform expand happens only when calling (get/export/format/build)Platform methods for the specific platform, whereas global expand happens on StyleDictionary instantiation already.

Refer to the lifecycle hooks diagram for a better overview.

When expanding globally, token metadata properties that are added by Style Dictionary such as name, filePath, path, attributes etc. are not present yet.
The advantage of global expand however, is having the expanded tokens (sd.tokens prop) available before doing any exporting to platforms.

If you configure it on the platform level, the metadata mentioned earlier is available and can be used to conditionally expand tokens. It also allows you to expand tokens for some platforms but not for others.
The downside there is needing to configure it for every platform separately.

Type Mapping

While our expand utility comes with a typesMap out of the box that aligns with the Design Token Community Group spec to convert composite subtype properties to defined DTCG types, you can also pass a custom typesMap that will allow you to extend or override it. A typesMap allows you to configure how object-value (composite) properties in the original token value should be mapped to the newly expanded individual tokens.

For example:

tokens-input.json
{
"value": {
"width": "2px",
"style": "solid",
"color": "#000"
},
"type": "border"
}

Here, according to the DTCG spec, you would probably want to map the "width" property to type "dimension" and "style" property to type "strokeStyle". "width" is more of a general property where we always want to map it to "dimension" but border "style" is more specific to the border composite type, therefore this typesMap makes sense:

config.json
{
"expand": {
"typesMap": {
"width": "dimension",
"border": {
"style": "strokeStyle"
}
}
}
}

Resulting in the following expanded output:

tokens-output.json
{
"width": {
"value": "2px",
"type": "dimension"
},
"style": {
"value": "solid",
"type": "strokeStyle"
},
"color": {
"value": "#000",
"type": "color"
}
}

Example

DTCG Type Map

Below is the standard DTCG type map that the expand utility comes out of the box with:

const DTCGTypesMap = {
// https://design-tokens.github.io/community-group/format/#stroke-style
strokeStyle: {
// does not yet have its own type defined, but is an enum of: "round" | "butt" | "square"
lineCap: 'other',
// note that this is spec'd to be a dimension array, which is unspecified in the spec for dimension
// generally speaking, transforms that match dimension type tokens do not account for this potentially being an array
// therefore we map it to "other" for now...
dashArray: 'other',
},
// https://design-tokens.github.io/community-group/format/#border
border: {
style: 'strokeStyle',
width: 'dimension',
},
// https://design-tokens.github.io/community-group/format/#transition
transition: {
delay: 'duration',
// needs more discussion https://github.com/design-tokens/community-group/issues/103
timingFunction: 'cubicBezier',
},
// https://design-tokens.github.io/community-group/format/#shadow
shadow: {
offsetX: 'dimension',
offsetY: 'dimension',
blur: 'dimension',
spread: 'dimension',
},
// https://design-tokens.github.io/community-group/format/#gradient
gradient: {
position: 'number',
},
// https://design-tokens.github.io/community-group/format/#typography
typography: {
fontSize: 'dimension',
letterSpacing: 'dimension',
lineHeight: 'number',
},
};