Skip to content
Back to skills

Design Token Sync

ASecurity

Generate design tokens from the atelier brand file (.atelier/brand.json): CSS custom properties, a Tailwind theme config, typed JS constants (tokens.js + tokens.d.ts) and a Figma Variables REST API body. Use when creating or regenerating design tokens, CSS variables, a Tailwind config, TypeScript color constants or Figma variables after brand colors or fonts change.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 13, 2026
designtypescriptbashnodeapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 8 files and shows the line behind each finding

Scanned October 13, 2026

npx -y skills add EthanY33/atelier --skill design-token-sync --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Design Token Sync?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Design Token Sync
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ethany33-design-token-sync/badge)](https://www.skillsdirectory.com/skills/ethany33-design-token-sync)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: design-token-sync
description: Generate design tokens from the atelier brand file (.atelier/brand.json): CSS custom properties, a Tailwind theme config, typed JS constants (tokens.js + tokens.d.ts) and a Figma Variables REST API body. Use when creating or regenerating design tokens, CSS variables, a Tailwind config, TypeScript color constants or Figma variables after brand colors or fonts change.
---

One-way: reads `.atelier/brand.json` (see brand-memory), writes token files. It never reads its outputs back and never calls Figma.

## Run

```bash
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" tokens              # project root = cwd, writes dist/tokens/
node "${CLAUDE_PLUGIN_ROOT}/bin/atelier" tokens --root ./site --out src/styles/tokens --targets css,dts
```

JS API. The module path is passed as an argument and turned into a file URL, so the import works with Windows, macOS and Linux paths:

```bash
node --input-type=module -e "const { pathToFileURL } = await import('node:url'); const m = await import(pathToFileURL(process.argv[1]).href); const files = await m.syncTokens({ projectRoot: '.', outDir: 'dist/tokens', targets: ['css', 'tailwind'] }); for (const f of files) console.log(f);" "${CLAUDE_SKILL_DIR}/index.mjs"
```

`syncTokens({ projectRoot, outDir, targets })` resolves to the absolute paths it wrote. The same module exports the pure emitters `emitCss`, `emitTailwind`, `emitDts`, `emitJs` and `emitFigmaVariables`: each takes a brand config object and returns the file content as a string.

## Options

| CLI | API | Default | Meaning |
|---|---|---|---|
| `[projectRoot]` or `--root <dir>` | `projectRoot` | cwd | Directory holding `.atelier/brand.json` |
| `--out <dir>` | `outDir` | `dist/tokens` | Output directory: absolute, or relative to the project root |
| `--targets <list>` | `targets` (array or comma string) | all | Any of `css`, `tailwind`, `dts`, `figma` |
| `-h`, `--help` | | | Print usage to stdout and exit 0 |

An unknown or empty target list is a usage error. All files are rendered before any is written.

## Output

| Target | File | Contents |
|---|---|---|
| css | `tokens.css` | `:root` with `--color-<key>` per palette entry and `--font-<slot>` per font |
| tailwind | `tailwind.config.js` | ESM `export default { theme: { extend: { colors, fontFamily } } }` |
| dts | `tokens.js` | ESM: frozen `colors` and `fonts` objects, plus one `export const` per color |
| dts | `tokens.d.ts` | Types for `tokens.js`: `ColorName`, `FontName`, literal-typed `colors`, `fonts` and consts |
| figma | `figma-variables.json` | Request body for Figma `POST /v1/files/:file_key/variables` |

The CLI prints one absolute path per line; the API returns them in the order tokens.css, tailwind.config.js, tokens.d.ts, figma-variables.json, tokens.js (only the requested targets).

`tokens.css` starts with `/* Generated by atelier design-token-sync. Do not edit by hand. */`. `tailwind.config.js`, `tokens.js` and `tokens.d.ts` start with the same text as a `//` comment. `figma-variables.json` has no header (JSON has no comments). Do not hand-edit: change brand.json and re-run.

Use the Tailwind file as a preset (`import tokens from './dist/tokens/tailwind.config.js'`, then `presets: [tokens]`), or with Tailwind v4 via `@config`.

## Exit codes

- `0`: files written, or `--help`.
- `2`: usage error (usage printed to stderr), or a failure such as a missing or invalid brand.json (`atelier: <message>` on stderr).

## Notes

- Fonts are emitted as CSS font-family lists. `Silkscreen, 'Courier New', monospace` becomes `"Silkscreen", "Courier New", monospace`: family names are quoted and escaped, generic families (serif, sans-serif, monospace, system-ui, ui-monospace and the like) and the vendor keywords `-apple-system` and `BlinkMacSystemFont` stay bare. Tailwind gets one array entry per family, with `sans-serif` (`monospace` for the mono slot) appended when the stack has no generic family. The vendor keywords do not count as one, because a browser without them skips them.
- Any palette key brand.json allows works (`brand-500`, `default`); object keys are quoted where needed. Named exports in tokens.js use safe identifiers: other keys are camelCased (`brand-500` -> `brand500`, `brand-primary` -> `brandPrimary`), reserved words and the names `colors`, `fonts` and `Object` get a trailing `_` (`default` -> `default_`, `Object` -> `Object_`), and a name that is already taken gets another `_`. `colors['brand-500']` always works with the original key, and tokens.d.ts marks each renamed export with its key.
- Figma body: a `palette` collection of COLOR variables (`{ r, g, b, a }` from 0 to 1) and a `typography` collection of STRING variables holding the first family of each stack, each collection with one mode named `default`. To apply it: `curl -X POST -H "X-Figma-Token: $FIGMA_TOKEN" -H "Content-Type: application/json" --data @dist/tokens/figma-variables.json https://api.figma.com/v1/files/<file_key>/variables`. Figma allows this endpoint only for full members of Enterprise orgs, with a token that has the `file_variables:write` scope. Every change is a CREATE, so posting twice duplicates the collections.
- Empty typography values are skipped in every output. Every value is escaped for its format, so a brand.json value cannot break out of a string or a declaration.

Files in this skill

  • SKILL.md5.2 KB
  • emitters/css.mjs1.1 KB
  • emitters/dts.mjs1.9 KB
  • emitters/figma.mjs2.7 KB
  • emitters/js.mjs2.3 KB
  • emitters/shared.mjs11.8 KB
  • emitters/tailwind.mjs1.7 KB
  • index.mjs6.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.