createTokens
Design token registry with hierarchical collections, alias resolution, and namespace support.
Usage
The createTokens composable allows you to define a collection of design tokens, which can be primitive values or aliases that reference other tokens. It provides a context for resolving these tokens, making it easy to access design values throughout your application.
import { createTokens } from '@vuetify/v0'
// Default behavior: fully flatten nested objects into dot-notation ids
const tokens = createTokens({
color: {
primary: '#3b82f6',
secondary: '#64748b',
info: '{color.primary}'
},
radius: {
sm: '4px',
md: '8px',
},
})
tokens.resolve('color.primary') // '#3b82f6'
tokens.resolve('color.info') // '#3b82f6' (alias resolved)
tokens.resolve('radius.md') // '8px'
const features = createTokens({
dark: true,
rtl: { value: true, variation: 'toggle' },
}, { flat: true })
// With flat: true, nested objects are kept as-is at their base id
features.resolve('rtl') // { value: true, variation: 'toggle' }Context / DI
Use createTokensContext to share a token registry across a component tree:
import { createTokensContext } from '@vuetify/v0'
export const [useTokens, provideTokens, tokens] =
createTokensContext({
namespace: 'my:tokens',
tokens: {
colors: {
primary: '#3b82f6',
secondary: '{colors.primary}', // alias
},
},
})
// In parent component
provideTokens()
// In child component
const tokens = useTokens()
tokens.resolve('colors.primary') // '#3b82f6'Architecture
createTokens extends createRegistry and powers token-based systems:
Options
createTokens
| Option | Type | Default | Notes |
|---|---|---|---|
flat | boolean | false | Keep nested objects as-is at their base key instead of flattening |
prefix | string | — | Prepend a string to every token ID on registration (e.g. 'color.') |
createTokensContext
Accepts all createTokens options plus:
| Option | Type | Default | Notes |
|---|---|---|---|
namespace | string | — | DI namespace string (e.g. 'my:tokens') |
tokens | TokenCollection | — | Initial token collection registered when the context is created |
Reactivity
createTokens uses minimal reactivity like its parent createRegistry. Token resolution is cached but not reactive.
For reactive theming Use useTheme which builds on createTokens with proper reactivity for theme switching.
Examples
FAQ
They control how nested objects are processed:
| Option | Behavior | Token IDs |
|---|---|---|
| default | Recursively flatten all nested objects | color.primary, color.secondary |
flat: true | Keep objects as-is at their base key | rtl → { value: true, ... } |
// default - flattens nested objects
const colors = createTokens({
color: { primary: '#3b82f6', secondary: '#64748b' }
})
colors.resolve('color.primary') // '#3b82f6'
colors.resolve('color') // undefined - 'color' itself isn't a token
// flat: true - preserves object structure
const features = createTokens({
rtl: { value: true, variation: 'toggle' }
}, { flat: true })
features.resolve('rtl') // { value: true, variation: 'toggle' }Use flat: true when your token values are objects you want to keep intact (e.g., feature flags with metadata).
The resolver detects cycles. It tracks visited aliases while resolving, and when it revisits one it logs a warning and returns undefined instead of recursing forever — no stack overflow:
const tokens = createTokens({
a: '{b}',
b: '{a}', // circular reference
})
tokens.resolve('a') // undefined — warns: Circular alias detected for "a"Even though cycles fail safe, design your token hierarchy as a directed acyclic graph (DAG). The Design Tokens spec↗︎ recommends keeping alias chains shallow:
No. Token values are static at registration time. For reactive design systems, resolve tokens into refs:
// Static tokens
const tokens = createTokens({
color: { primary: '#3b82f6', dark: '#1e3a8a' }
})
// Reactive usage
const isDark = ref(false)
const primaryColor = computed(() =>
tokens.resolve(isDark.value ? 'color.dark' : 'color.primary')
)For fully reactive theming, see useTheme which builds on createTokens.
No. Aliases only resolve within the same createTokens instance:
const colors = createTokens({ primary: '#3b82f6' })
const spacing = createTokens({ gap: '{primary}' }) // Won't resolve - different instance
spacing.resolve('gap') // undefined - '{primary}' isn't registered in this instance (warns)To share tokens across collections, use a single unified token set or compose at the application level.
Use register and unregister inherited from createRegistry:
const tokens = createTokens({
color: { primary: '#3b82f6' }
})
// Update a token
tokens.unregister('color.primary')
tokens.register({ id: 'color.primary', value: '#ef4444' })
tokens.resolve('color.primary') // '#ef4444'For theme switching, consider useTheme which handles this pattern with proper reactivity.
Alias resolution is recursive string replacement—each {alias} triggers another resolve() call. For deep chains:
token → alias1 → alias2 → alias3 → value
↓ ↓ ↓
resolve resolve resolveKeep alias chains shallow (2-3 levels max) for predictable performance. If you need deep composition, resolve intermediate values at build time.
createTokens is inspired by the Design Tokens Community Group specification↗︎. Key alignments:
| Spec Concept | createTokens |
|---|---|
| Token value | register({ id, value }) |
Alias syntax {path.to.token} | Supported via resolve() |
| Nested groups | Flattened with dot notation |
The spec is still in draft, so createTokens focuses on the stable patterns. For CSS custom property output, pair with useTheme which handles CSS variable generation.