Utilities

Transformer

SXL Token Transformer: YAML-first CLI for deterministic conversion of JSON design tokens to CSS, SCSS, Swift, UIKit, Kotlin, Android XML, and JSON manifests.

What Is Transformer

SXL Token Transformer (@sxl-studio/token-transformer) is a CLI utility that converts token JSON into production-ready platform outputs:

  • CSS custom properties
  • SCSS variables
  • Swift constants and typed specs for Xcode/SwiftUI pipelines
  • UIKit constants and typed specs for iOS UIKit pipelines
  • Kotlin constants and typed specs for Android Compose pipelines
  • Android XML resources (colors.xml, dimens.xml, strings.xml, bools.xml, integers.xml)
  • JSON manifest metadata for documentation, Storybook token viewers, devtools, audits, and migrations

Transformer is intended for deterministic, policy-driven exports where output shape and token selection are configured explicitly.

What It Supports

  • YAML-only config (version: 1) with strict schema validation
  • Collection/mode selection from token project config.json
  • Optional auto-discovery of config.json in source.tokenDir when source.configFile is omitted
  • Inline inheritance config via top-level projectConfig (no config.json required)
  • Config composition from multiple YAML files via extends
  • File/glob selection and mixed selectors in one token set
  • Ordered merge of token sources
  • Collision strategies: error | suffix | namespace-by-file | namespace-by-mode
  • Token-set unresolved alias policy: error | warn | ignore
  • Alias resolution with cycle/depth protection
  • Math expressions (+ - * / %, round, floor, ceil, clamp, etc.)
  • figma.modify color modifiers (including chained modifiers)
  • Interactive issue handling with debug report generation
  • Component auto-splitting by source files (splitBySourceFile, including prefixPattern)
  • First-class manifest output (platform: manifest) from the same resolved token graph as CSS/native outputs
  • Swift, SwiftUI, and UIKit support types generated with Sendable conformance for Swift 6 strict-concurrency projects

template, composition, and grid token types are intentionally excluded from transformation.

Type Support Matrix (CSS / SCSS / Swift / UIKit / Kotlin)

Supported:

  • color, gradient, img, fill, opacity
  • dimension, number, spacing, sizing
  • border, borderWidth, borderRadius, strokeStyle
  • typography, fontFamily, fontWeight, fontStyle, fontSize, lineHeight, letterSpacing, paragraphSpacing, paragraphIndent, textCase, textDecoration
  • shadow, backdrop-blur, blur, glass, effects
  • boolean, text
  • transition, duration, cubicBezier (value/spec tokens only; no auto-apply helpers to UI elements)

Excluded:

  • template, composition, grid

Manifest supports the same allowed token types as CSS/SCSS/Swift/UIKit/Kotlin and never emits forbidden template, composition, grid tokens.

No-hallucination behavior:

  • Invalid token values are never fabricated: token gets error and is not emitted.
  • Unresolved alias behavior is controlled by tokenSet unresolvedAliases (error | warn | ignore).
  • Recommended production profile: unsupportedTypes.default: error.

Warning (Android XML): XML output is intentionally native-limited and is not full token parity with CSS/SCSS/Swift/UIKit/Kotlin. Transformer emits only valid Android primitives/resources (color, dimen, string, bool, integer) and supported drawables (for gradients/fill/img). Complex token objects that have no native XML resource representation are not serialized and are reported as diagnostics.

Android XML Coverage (Warning)

Android XML generation is designed for native Android resource compatibility first, not 1:1 support for every token type.

Supported in XML output:

  • primitive resources: color, dimension/spacing/sizing, number (integer), text, boolean
  • typography decomposition to primitive resources (fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, etc.)
  • drawable resources for supported gradient/fill/img structures

Not fully representable in XML (reported as diagnostics):

  • advanced composite effects (effects, complex glass, complex blur/backdrop chains)
  • transition/easing semantics (transition, duration, cubicBezier) as runtime animation logic
  • token objects that require runtime APIs instead of static resource XML

Swift / UIKit concurrency compatibility

Swift and UIKit outputs include support structs/enums with Sendable conformance, so generated token specs can be used in Swift 6 strict-concurrency codebases without adding local wrappers. This applies to generated token specification types for fills, gradients, typography, shadows/effects, borders, stroke styles, images, and transitions.

Install

BASH
npm install --save-dev @sxl-studio/token-transformer
# or
pnpm add -D @sxl-studio/token-transformer
# or
yarn add -D @sxl-studio/token-transformer

CLI Commands

BASH
# smart incremental sync (default mode)
npx sxl-transform sync --config ./sxl-transform.config.yaml
# or, with pnpm
pnpm exec sxl-transform sync --config ./sxl-transform.config.yaml

# force full rebuild
npx sxl-transform sync --config ./sxl-transform.config.yaml --force

# config validation only
npx sxl-transform validate-config --config ./sxl-transform.config.yaml

# generate starter YAML config
npx sxl-transform init --path ./sxl-transform.config.yaml

# command-specific help
npx sxl-transform help
npx sxl-transform help sync
npx sxl-transform help validate-config
npx sxl-transform help init
npx sxl-transform help version
npx sxl-transform validate-config --help

# version
npx sxl-transform version
npx sxl-transform --version

CLI help

The CLI has general help and command-specific help:

BASH
sxl-transform help
sxl-transform help sync
sxl-transform help validate-config
sxl-transform help init
sxl-transform help version

Equivalent shortcuts:

BASH
sxl-transform --help
sxl-transform -h
sxl-transform sync --help
sxl-transform validate-config --help
sxl-transform init --help
sxl-transform --version
sxl-transform -v

Help behavior:

  • sxl-transform help prints the command list, issue modes, state behavior, and scope flags.
  • sxl-transform help <command> prints options and behavior for one command.
  • sxl-transform <command> --help is equivalent to help <command>.
  • sync is the default command, so sxl-transform --config ./sxl-transform.config.yaml is valid.
  • version, --version, and -v print the installed package version.

Build modes

  • smart (default): uses previous run state and rebuilds only affected outputs.
  • force: rebuilds all outputs from config.
BASH
npx sxl-transform sync --config ./sxl-transform.config.yaml --mode smart
npx sxl-transform sync --config ./sxl-transform.config.yaml --mode force

Scoped run examples:

BASH
# output-id scope (repeatable)
npx sxl-transform sync --config ./sxl-transform.config.yaml --only-output css-app --only-output swift-app

# file scope (glob)
npx sxl-transform sync --config ./sxl-transform.config.yaml --only-file "modes/dark.css"
npx sxl-transform sync --config ./sxl-transform.config.yaml --only-file "css-app:modes/dark.css"

State file:

  • default path: <config-name>.state.json (next to config)
  • override: --state-file ./custom/path/transform.state.json

Issue action modes:

  • ask (default interactive mode)
  • debug-stop
  • debug-continue
  • autofix
  • skip

Compatibility alias:

  • --issues <mode> works as alias for --issue-action <mode>

Config Model (YAML)

YAML
version: 1
source:
  tokenDir: ./tokens
  # optional: auto-uses ./tokens/config.json if present
  # configFile: config.json
  include: ["**/*.json"]
  exclude: ["config.json", "**/diff-id*.json"]

projectConfig:
  collections:
    - name: Core
      modes:
        - name: Default
          files:
            core/palettes.json: enabled

options:
  remBase: 16
  collisionStrategy: error
  maxAliasDepth: 20
  unsupportedTypes:
    default: error
    types:
      template: skip
      composition: skip
      grid: skip

tokenSets:
  - id: app-root
    unresolvedAliases: error
    selectors:
      - collection: Core
        mode: Default
      - collection: Product
        mode: Default
      - collection: Themes
        mode: Light
        refModeMap:
          Product: Default
          Core: Default

outputs:
  - id: css-root
    platform: css
    outputDir: ./design-system/css/customer-app
    prefix: ds
    suffix: v2
    codeSyntax:
      source: extension-first
      template: "{var(--css-variable)}"
    resolveAliases: false
    splitEffects: true
    showDescriptions: true
    files:
      - tokenSet: app-root
        output: root.css

  - id: tokens-manifest
    platform: manifest
    outputDir: ./design-system/manifest/customer-app
    files:
      - tokenSet: app-root
        output: tokens-manifest.json
        options:
          schemaVersion: "1.0"
          includeResolvedValue: true
          includeOriginalValue: true
          includeReferences: true
          includeSource: true
          includeExtensions: false
          includePrivate: true
          groupBy: flat

Inheritance Configuration (Two Supported Ways)

Use collection + mode selectors only when at least one inheritance source exists:

  1. Token project config file:
    • source.configFile: config.json (or omit source.configFile and keep config.json inside source.tokenDir)
  2. Inline YAML inheritance:
    • define top-level projectConfig with collections -> modes -> files

If neither source is configured, pipeline fails with PROJECT_CONFIG_REQUIRED and debug report includes ready-to-copy examples plus docs link.

Split Configs by Project / Platform

You can split one large config into several focused configs and run each independently with --config.

Example layout:

  • sxl-transform.customer-app.config.yaml
  • sxl-transform.admin-panel.config.yaml
  • sxl-transform.marketing-site.config.yaml
  • sxl-transform-components.config.yaml
  • optional platform-specific configs (*-css.config.yaml, *-scss.config.yaml, *-swift.config.yaml, *-kotlin.config.yaml, *-manifest.config.yaml)

Use extends to share common base parts:

YAML
# sxl-transform.customer-app.css.config.yaml
extends:
  - ./configs/sxl-transform.base.config.yaml
  - ./configs/sxl-transform.customer-app.tokensets.config.yaml
outputs:
  - id: css-customer-app
    platform: css
    outputDir: ./design-system/css/customer-app
    files:
      - tokenSet: customer-app-root
        output: root.css

Selector behavior and resolver scope

A selector must define either:

  • collection + mode (token project mode selection), or
  • files / include patterns (direct file selection).

You can combine selectors inside one token set; files are merged in declared order.

YAML
tokenSets:
  - id: semantic-root
    unresolvedAliases: warn
    selectors:
      - collection: Themes
        mode: Light
        includeRefs: true
        refModeMap:
          Product: Default
          Core: Default
      - include:
          - components/**/*.style.json
        exclude:
          - components/**/__draft__/*.json

Selector keys:

  • includeRefs -> include referenced collection/mode files into resolver scope (true by default)
  • refModeMap -> force deterministic mode mapping for referenced collections
  • exclude -> remove files from both emit and resolver file sets

unresolvedAliases policy is set per token set:

  • error -> unresolved aliases fail the run
  • warn -> report diagnostics but continue
  • ignore -> suppress unresolved alias diagnostics for that set

Output behavior and defaults

Per output:

  • resolveAliases defaults to false for css and scss;
  • resolveAliases defaults to true for swift, uikit, kotlin, xml, manifest;
  • splitEffects defaults to true;
  • showDescriptions defaults to true.
  • SCSS output is token-first: load root files before component files in your stylesheet entrypoint so cross-file $token references resolve.
  • Manifest output emits JSON and does not depend on Style Dictionary or postprocess scripts.
  • optional codeSyntax fallback is available per output:
    • source: extension-first | config-first | extension-only | config-only
    • template: one of
      • {var(--css-variable)}
      • {$sass-variable}
      • {@less-variable}
      • {UpperCamelCase}
      • {lowerCamelCase}
      • {UPPER_SNAKE_CASE}
      • {lower_snake_case}

codeSyntax.source priority rules:

  • extension-first (default): token $extensions.figma.codeSyntax wins, output template is fallback.
  • config-first: output template wins, token extension is fallback.
  • extension-only: use token extension only.
  • config-only: use output template only.

Each output must define at least one of files, bundles, bundlesFromCollections, or indexes.

Each outputs[].files[] entry must define one of:

  • output (static file path), or
  • splitBySourceFile (dynamic per-source-file output generation).

Manifest Output

Use platform: manifest when consumers need token metadata for documentation, Storybook foundations, token viewers, devtools, audits, or migration tooling.

The manifest is generated from the same resolved token graph as other outputs for the selected tokenSet. Each token entry includes name, cssVar, path, type, sourceFile, references, and effective value. By default it also includes resolvedValue and originalValue.

level and weight are not inferred from token path or collection names. Transformer reads them from token extensions (level, sxl.level, sxl.weight) when present; otherwise they are null.

Manifest options:

  • schemaVersion: top-level manifest schema string, default "1.0"
  • includeResolvedValue: include resolvedValue, default true
  • includeOriginalValue: include original JSON $value, default true
  • includeReferences: extract references from the original value before resolve, default true
  • includeSource: include collection, mode, tokenSet, level, default true
  • includeExtensions: include token $extensions, default false
  • includePrivate: include tokens hidden with $extensions.figma.hide, default true
  • cssVarPrefix / cssVarSuffix: override CSS variable affixes used only in manifest metadata
  • groupBy: flat | collection | mode | file, default flat

Example with several manifest files:

YAML
outputs:
  - id: manifest-customer-app
    platform: manifest
    outputDir: ./design-system/manifest/customer-app
    files:
      - tokenSet: customer-app-root
        output: tokens-manifest.json
      - tokenSet: customer-app-core
        output: manifest/core.json
      - tokenSet: customer-app-components
        output: manifest/components.json
        options:
          groupBy: file

Selective CLI scope:

  • --only-output <id>: process specific output ids only (repeatable).
  • --only-file <glob>: process specific output files only (repeatable).
  • In --only-file mode stale cleanup is not applied outside selected files.

Custom Formatters (Per Type / Per Platform)

Transformer supports modular output hooks so users can override behavior without forking the package.

You can attach a module per output via outputs[].options.customFormatters:

YAML
outputs:
  - id: css-main
    platform: css
    outputDir: ./out/css
    files:
      - tokenSet: root
        output: root.css
    options:
      customFormatters:
        module: ./transform-hooks.mjs
        exportName: plugin

Hook module shape:

JS
/** @type {import("@sxl-studio/token-transformer").CustomFormatterPlugin} */
export const plugin = {
  tokenTypeFormatters: {
    css: {
      color: ({ token }) => ({ ...token, resolvedValue: "#00FF00", value: "#00FF00" }),
    },
  },
  platformEmitters: {
    css: ({ emitDefault, input, relativeOutput }) => {
      const base = emitDefault(input, relativeOutput);
      return { ...base, content: `${base.content}\n/* custom footer */\n` };
    },
  },
};

Behavior:

  • tokenTypeFormatters[platform][type] overrides one token type formatter.
  • Return undefined to keep default token.
  • Return null to drop token.
  • Return FlatToken or FlatToken[] to replace/expand token output.
  • platformEmitters[platform] can override whole platform emission for that output.

Diagnostics:

  • malformed or missing hook module produces explicit CUSTOM_FORMATTER_* diagnostics (error / warn), no silent fallback.

Multi-Mode Example (Root + Modes)

YAML
tokenSets:
  - id: customer-app-root
    selectors:
      - collection: Core
        mode: Default
      - collection: Product
        mode: Default
      - collection: Themes
        mode: Light
      - collection: Breakpoints
        mode: Desktop
      - collection: Surface
        mode: Low

  - id: customer-app-dark
    selectors:
      - collection: Themes
        mode: Dark

outputs:
  - id: css-customer-app
    platform: css
    outputDir: ./design-system/css/customer-app
    resolveAliases: false
    files:
      - tokenSet: customer-app-root
        output: root.css
      - tokenSet: customer-app-dark
        output: modes/dark.css

Auto-Generate Component CSS Files

To generate one file per component style token file (without adding new config blocks each time):

YAML
tokenSets:
  - id: components-style
    unresolvedAliases: warn
    selectors:
      - files:
          - components/**/*.style.json

outputs:
  - id: css-components
    platform: css
    outputDir: ./design-system/components
    files:
      - tokenSet: components-style
        splitBySourceFile:
          include:
            - components/**/*.style.json
          exclude:
            - components/**/__draft__/*.json
          outputPattern: "{component}/{component}.css"
          prefixPattern: "c-{component}-"
          suffixPattern: "-v2"

If you add a new components/WAccordion/.../WAccordion.style.json, the next run automatically produces ds/components/WAccordion/WAccordion.css.

splitBySourceFile placeholders:

  • {sourceFile} -> full relative source file path
  • {sourceDir} -> source directory
  • {sourceBase} -> file name with extension
  • {sourceName} -> file name without extension
  • {sourceStem} -> sourceName without .style suffix
  • {component} -> inferred component segment (components/<name>/...) or fallback stem
  • {fileName} -> alias of {sourceStem}

Naming affixes:

  • outputs[].prefix / outputs[].suffix apply to all generated token names in the output.
  • outputs[].files[].prefix / outputs[].files[].suffix override affixes per mapping.
  • splitBySourceFile.prefixPattern / splitBySourceFile.suffixPattern set dynamic affixes for split-generated files.

CSS / SCSS Output Contract

CSS output uses :root by default. Set selector on a file mapping when a mode or component file must be emitted under a specific runtime selector:

YAML
outputs:
  - id: css-app
    platform: css
    outputDir: ./design-system/styles/css
    files:
      - tokenSet: app-root
        output: root.css
        selector: ":root"
      - tokenSet: app-dark
        output: themes/dark.css
        selector: "[data-theme='dark']"
      - tokenSet: components-style
        splitBySourceFile:
          include:
            - components/**/*.style.json
          outputPattern: "{component}/{component}.css"
        selector:
          - ":root"
          - "[data-component='{component}']"

For split files, selector supports the same placeholders as outputPattern, including {component}, {sourceStem}, and {sourceFile}. Selector arrays are emitted as a comma-separated selector list.

Important platform rule:

  • selector is applied only for platform: css.
  • If selector is configured for scss, swift, uikit, kotlin, xml, or manifest, Transformer reports SELECTOR_UNSUPPORTED_PLATFORM and ignores it.

Generate CSS or SCSS entrypoints with indexes:

YAML
outputs:
  - id: css-app
    platform: css
    outputDir: ./design-system/styles/css
    files:
      - tokenSet: app-root
        output: root.css
      - tokenSet: app-dark
        output: themes/dark.css
    indexes:
      - output: index.css
        imports:
          - ./root.css
        includeGenerated:
          - themes/*.css
          - components/**/*.css
        exclude:
          - index.css
          - "**/*.internal.css"
        sort: generated-order # generated-order | alpha
        skipMissing: true
        strict: false

Index behavior:

  • CSS indexes emit @import "...";.
  • SCSS indexes emit @use "..." as *;.
  • indexes are supported only for css and scss; native and XML outputs report INDEX_UNSUPPORTED_PLATFORM.
  • Explicit imports are resolved relative to the index file. Missing explicit imports are errors unless skipMissing: true.
  • includeGenerated matches generated files from the same output. Smart mode uses the current run plus previous state, so rebuilding only an index does not drop imports to unchanged files.
  • Index files are tracked in state and removed by stale cleanup when deleted from config or when their output becomes stale.
  • Index files participate in --only-output and --only-file; use output-scoped file patterns like css-app:index.css for targeted rebuilds.
  • Self-imports and duplicate output paths are reported as errors.

Use bundles when several source token files must be grouped into one output without creating a separate tokenSet:

YAML
outputs:
  - id: css-components
    platform: css
    outputDir: ./design-system/components
    files:
      - tokenSet: components-style
        splitBySourceFile:
          include:
            - components/**/*.style.json
          exclude:
            - components/WBanner/**/*.style.json
          outputPattern: "{component}/{component}.css"
    bundles:
      - tokenSet: components-style
        output: WBanner/WBanner.css
        include:
          - components/WBanner/**/*.style.json
        exclude: []
        selector: ":root"

Bundles use the same token graph, resolver, alias policy, unsupported-type policy, token filters, custom formatters, and platform emitter as regular files. They are not string concatenation of already generated files. Bundles are available for all output platforms, but selector inside a bundle is still CSS-only.

Bundle-only outputs are valid. This is useful when a project wants grouped component artifacts without also generating one file per source token file.

Component bundles from config.json / projectConfig

Use bundlesFromCollections when component bundle groups are already described in source.configFile or top-level projectConfig. Transformer reads enabled mode.files from matching collections and emits one bundle per collection.

YAML
outputs:
  - id: css-components
    platform: css
    outputDir: ./design-system/components
    resolveAliases: false
    files:
      - tokenSet: components-style
        splitBySourceFile:
          include:
            - components/**/*.style.json
          excludeBundledSources: true
          outputPattern: "{fileName}.css"
    bundlesFromCollections:
      - tokenSet: components-style
        mode: Default
        include:
          - WBanner
          - WInput
          - WTab
        fileInclude:
          - components/**/*.style.json
        fileExclude:
          - "**/__draft__/*.json"
        outputPattern: "{collection}.css"
        selector:
          - ":root"
          - "[data-theme='dark']"
        strict: true
    indexes:
      - output: index.css
        includeGenerated:
          - "**/*.css"
        exclude:
          - index.css
        sort: alpha

Behavior:

  • source.configFile and top-level projectConfig are both supported.
  • Only files with status enabled in mode.files are used.
  • fileInclude / fileExclude filter the collection files before bundle generation.
  • Tokens are still taken from tokenSet; bundle content is limited to tokens whose sourceFile belongs to the matched collection files.
  • Generated collection bundles pass through the same pipeline as manual bundles: platform emitter, selector, filter, prefix/suffix, unsupported-token policy, alias policy, custom formatters, state/smart mode, stale cleanup, --only-output, and --only-file.
  • indexes[].includeGenerated sees collection bundles the same way it sees normal generated files.

Collection matching:

YAML
bundlesFromCollections:
  - tokenSet: components-style
    mode: Default
    collections:
      include: ["W*"]
      exclude: ["WLegacy*"]
    fileInclude: ["components/**/*.style.json"]
    outputPattern: "{collectionKebab}.css"

Flat form is also supported:

YAML
bundlesFromCollections:
  - tokenSet: components-style
    mode: Default
    include: ["WBanner", "WInput"]
    exclude: []
    outputPattern: "{collection}.css"

Supported outputPattern placeholders:

  • {collection}, {mode}
  • {collectionKebab}, {collectionSnake}, {collectionLower}
  • {modeKebab}, {modeSnake}, {modeLower}

Avoiding duplicate split files:

  • splitBySourceFile.excludeBundledSources: true automatically excludes source files used by manual bundles and bundlesFromCollections for the same tokenSet.
  • splitBySourceFile.excludeFromCollections explicitly excludes files from selected collections without requiring bundle generation:
YAML
splitBySourceFile:
  include:
    - components/**/*.style.json
  excludeFromCollections:
    mode: Default
    include:
      - WBanner
      - WInput
  outputPattern: "{fileName}.css"

Diagnostics:

  • Missing project config emits BUNDLE_FROM_COLLECTION_PROJECT_CONFIG_REQUIRED.
  • Missing collections emit BUNDLE_FROM_COLLECTION_NOT_FOUND.
  • Missing mode emits BUNDLE_FROM_COLLECTION_MODE_NOT_FOUND.
  • A collection/mode with no matched enabled files emits BUNDLE_FROM_COLLECTION_EMPTY.
  • With strict: true, missing config/collection/mode diagnostics are errors; otherwise they are warnings and the bundle is skipped.

Typography Mapping

For typography tokens, Transformer exports at least:

  • fontFamily
  • fontSize
  • lineHeight
  • fontWeight

and additionally supports:

  • letterSpacing
  • textCase
  • textDecoration
  • verticalTrim / leadingTrim

Platform behavior:

  • CSS:
    • always emits one typography shorthand variable using base fields (fontWeight fontSize/lineHeight fontFamily, plus optional fontStyle)
    • does not emit base duplicate leaves (-font-family, -font-weight, -font-size, -line-height)
    • emits optional leaves only when those fields exist in token JSON:
      • -letter-spacing
      • -paragraph-indent
      • -paragraph-spacing
      • -text-transform + -font-variant-caps (from textCase)
      • -text-decoration-line (from textDecoration)
      • -leading-trim (from verticalTrim / leadingTrim)
  • Swift/Kotlin: typed typography specs include all fields above
  • XML: typography is decomposed into primitive resources (family/weight as strings, size/line-height/letter-spacing as dimens)

Note: verticalTrim / leadingTrim is exported as semantic token data. Browser support for trim-related CSS is still uneven; validate target browser matrix before relying on it in production.

Issue Handling Menu and Debug Report

When issues are found (unresolved aliases, broken alias syntax, etc.), sync can show an interactive action menu:

  1. Create debug file and stop
  2. Create debug file and continue
  3. Auto-fix simple alias syntax and continue
  4. Skip broken tokens and continue

Non-interactive runs can use:

BASH
npx sxl-transform sync --config ./sxl-transform.config.yaml --issue-action debug-stop
npx sxl-transform sync --config ./sxl-transform.config.yaml --issue-action debug-continue
npx sxl-transform sync --config ./sxl-transform.config.yaml --issue-action autofix
npx sxl-transform sync --config ./sxl-transform.config.yaml --issue-action skip

Debug file options:

BASH
# default file name: <config-name>.debug.md
npx sxl-transform sync --config ./sxl-transform.config.yaml --debug-report

# custom path via dedicated flag
npx sxl-transform sync --config ./sxl-transform.config.yaml --debug-file ./reports/transform.debug.md

# custom path via --debug-report value
npx sxl-transform sync --config ./sxl-transform.config.yaml --debug-report ./reports/transform.debug.md

If inheritance is not configured for collection+mode selectors, the debug file contains:

Project-level scripts example:

JSON
{
  "scripts": {
    "tokens:validate": "sxl-transform validate-config --config ./sxl-transform.config.yaml",
    "tokens:build": "sxl-transform sync --config ./sxl-transform.config.yaml --issue-action debug-stop",
    "tokens:build:ci": "sxl-transform sync --config ./sxl-transform.config.yaml --issue-action skip"
  }
}

Quality Gates

For an end-user project, the usual checks are:

BASH
npm run tokens:validate
npm run tokens:build:ci

FAQ

Why did I get unresolved alias warnings for a mode/component set?

Most often the selected token set does not include the referenced collection/mode files in resolver scope. Check selector composition, includeRefs, and refModeMap.

Should CSS keep aliases while Swift/Kotlin resolve values?

Yes. Typical mode-switch workflows keep CSS aliases (resolveAliases: false) and resolve concrete values for Swift/Kotlin (resolveAliases: true).

Why are some token types missing from Android XML output?

XML output is intentionally limited to primitive resources. Complex visual structures (for example advanced effects) are emitted to CSS/Swift/Kotlin and reported as unsupported for XML.

For color tokens that store linear-gradient(...), transformer emits native Android gradient drawables (drawable/*.xml) instead of writing invalid entries to colors.xml.

Is [object Object] expected anywhere?

No. Transformer rejects unsupported object serialization paths and reports diagnostics instead of emitting invalid placeholders.

Specs References