Theming
How to customise your design system with JSON tokens and the Toucan CLI.
How Theming Works
Toucan uses a JSON-to-CSS pipeline. Your theme is defined entirely in DTCG JSON token files — raw values, alias mappings, and system bindings. The toucan CLI compiles these into a single toucan.css file that your app imports.
There is no separate "theme layer" or CSS override file. Your JSON tokens are your theme. To change the theme, change the tokens and rebuild.
The Default Preset
The @toucan-ui/tokens package ships a default preset — neutral system fonts, a balanced colour palette, and sensible spacing. A site that uses the default preset renders cleanly out of the box.
{
"tokens": "@toucan-ui/tokens/presets/default",
"outDir": "./css"
}npx toucan build/* All tokens + component CSS in one file */
@import './css/toucan.css';Customising with the Wizard
The Wiz'rd lets you visually configure colours, typography, spacing, and component tokens. It outputs a ZIP of DTCG JSON files that you extract into your project and compile with the CLI.
# 1. Extract wizard download
unzip ~/Downloads/my-theme-tokens.zip -d ./tokens/my-theme
# 2. Point config at your tokens
# toucan.config.json → { "tokens": "./tokens/my-theme", "outDir": "./css" }
# 3. Build
npx toucan buildThe wizard JSON is also compatible with Figma token plugins and can be used as a source for other platform targets (Flutter, iOS, Android) via Style Dictionary.
Writing Tokens by Hand
For full control, create your own DTCG JSON files. Organise them into three directories:
raw/ — Primitive values
Colour palettes, spacing scales, font stacks, shadows. These are the concrete values everything else references.
{
"color": {
"brand": {
"500": { "$value": "#7c3aed", "$type": "color" },
"600": { "$value": "#6d28d9", "$type": "color" },
"700": { "$value": "#5b21b6", "$type": "color" }
}
}
}alias/ — Semantic mappings
Map semantic roles to raw values. A single alias change cascades to every component that references it.
{
"color": {
"primary": { "$value": "{color.brand.500}", "$type": "color" },
"primary-hover": { "$value": "{color.brand.600}", "$type": "color" },
"primary-active": { "$value": "{color.brand.700}", "$type": "color" }
}
}system/ — Component bindings
Fine-tune individual component tokens when alias changes aren't granular enough. Most themes only need raw and alias customisation.
{
"button": {
"radius": { "$value": "{radius.sm}", "$type": "dimension" },
"font-weight": { "$value": "{font.weight.semibold}", "$type": "fontWeight" }
}
}Dark Mode
Add a dark/ directory alongside your token tiers. The CLI compiles dark tokens into CSS scoped to [data-mode="dark"]. Toggle dark mode by setting the attribute on any ancestor element.
// Enable dark mode
<html data-mode="dark">
// Or scope to a section
<div data-mode="dark">
<Button>Dark-styled button</Button>
</div>Example Themes
The example pages in this docs site demonstrate different token configurations in action. Each example uses a different set of JSON tokens compiled through the same CLI pipeline — the same components adapt to completely different visual styles without changing any component code.