Import JSON design tokens directly into your SCSS files. Supports W3C DTCG and Style Dictionary formats with alias resolution, flat variables, and Sass map output.
Poops now integrates sass-token-importer, a custom Dart Sass importer that lets you @use JSON token files as if they were SCSS modules. Define your design tokens in JSON once and use them everywhere — no manual SCSS variable files to keep in sync.
Create a tokens directory with your JSON token files. Both W3C DTCG and Style Dictionary formats are auto-detected.
tokens/colors.json (W3C DTCG format):
{
"color": {
"$type": "color",
"primary": { "$value": "#0066cc" },
"secondary": { "$value": "#ff6600" },
"accent": { "$value": "#9b59b6" },
"text": { "$value": "#333333" },
"background": { "$value": "#f5f5f5" },
"link": { "$value": "{color.primary}" }
}
}
tokens/spacing.json:
{
"spacing": {
"$type": "dimension",
"xs": { "$value": "4px" },
"sm": { "$value": "8px" },
"md": { "$value": "16px" },
"lg": { "$value": "32px" },
"xl": { "$value": "64px" }
}
}
Add tokenPaths to your styles config in poops.json:
{
"styles": [
{
"in": "src/scss/index.scss",
"out": "dist/css/styles.css",
"options": {
"tokenPaths": ["src/tokens"]
}
}
]
}
Then use the token: prefix in your SCSS to import them:
@use "token:colors" as c;
@use "token:spacing" as s;
.token-test {
color: c.$color-primary;
background-color: c.$color-background;
a {
color: c.$color-link;
&:hover {
color: c.$color-secondary;
}
}
padding: s.$spacing-md;
margin-bottom: s.$spacing-lg;
&__header {
color: c.$color-accent;
padding: s.$spacing-sm s.$spacing-md;
}
&__body {
color: c.$color-text;
padding: s.$spacing-md;
gap: s.$spacing-xs;
}
}
Token values can reference other tokens using curly-brace syntax. In the example above, link resolves to the value of color.primary (#0066cc). Chained aliases are resolved in topological order, and circular references throw an error. Disable with "resolveAliases": false in your options.
By default, tokens are generated as flat SCSS variables ($color-primary: #0066cc). Set "tokenOutput": "map" to generate nested Sass maps instead:
{
"options": {
"tokenPaths": ["src/tokens"],
"tokenOutput": "map"
}
}
@use "sass:map";
@use "token:colors" as c;
.btn {
color: map.get(c.$color, primary);
}
| Type | Example | SCSS Output |
|---|---|---|
color |
"#0066cc" |
#0066cc |
dimension |
"16px" |
16px |
fontFamily |
["Helvetica", "sans-serif"] |
("Helvetica", sans-serif) |
fontWeight |
700 |
700 |
duration |
"200ms" |
200ms |
cubicBezier |
[0.42, 0, 0.58, 1] |
cubic-bezier(0.42, 0, 0.58, 1) |
typography |
composite | Sass map |
shadow |
composite | Sass map |
border |
composite | Sass map |
Point to multiple directories if your tokens are split across packages or folders:
{
"options": {
"tokenPaths": ["src/tokens", "node_modules/@my-org/tokens/dist"]
}
}
token: prefixThe token: prefix explicitly targets the token importer, avoiding ambiguity when you have both a colors.json token file and a _colors.scss partial. Without it, Sass tries importers in registration order — which works, but the prefix makes the intent clear.