One Source of Truth for Your System
Design Tokens & CSS Variables
Theme tokens are exposed as CSS custom properties, enabling runtime theming and integration with design tooling.
What you'll learn
- Read tokens at runtime via var(--color-brand)
- Re-theme by overriding variables within a scope
- Use token namespaces to control which utilities are generated
A @theme token is not a build-time constant — it compiles to a live CSS custom property on :root. That single fact unlocks runtime theming.
Tokens at Runtime
After defining --color-brand, it exists in the browser as a regular variable:
:root {
--color-brand: oklch(0.62 0.19 256);
}
.custom-callout {
border-left: 4px solid var(--color-brand);
} JavaScript can read or set it with getComputedStyle and style.setProperty, so the same token drives utilities, custom CSS, and dynamic behaviour.
Re-Theming by Scope
Override the variable inside a class or attribute and every *-brand utility under that scope re-skins instantly — no rebuild:
.theme-acme {
--color-brand: oklch(0.55 0.21 25);
}
.theme-globex {
--color-brand: oklch(0.7 0.15 160);
} <section class="theme-acme">
<button class="bg-brand text-white">Acme red</button>
</section> This is how multi-brand sites and per-user themes work in v4: one token, scoped overrides.
Namespaces Drive Generation
The token namespace is meaningful, not cosmetic. It tells Tailwind which family of utilities to emit:
@theme {
--color-ink: oklch(0.2 0 0);
--spacing-bay: 3rem;
--radius-pill: 9999px;
--text-display: 3.5rem;
} --color-* becomes color utilities, --spacing-* becomes spacing utilities, --radius-* becomes rounded-*, and --text-* becomes font-size utilities. Keeping tokens correctly namespaced is what keeps the generated utility surface coherent.