Tailwind v4 et tokens : arrêter de se battre avec config.js
Tailwind v4 a viré tailwind.config.js. Voici comment exposer ses tokens (couleurs, fonts) via CSS variables et @theme inline, sans perdre l'autocomplétion ni le dark mode.
Tailwind v4 a viré tailwind.config.js. Plus de fichier de config JavaScript, plus de theme.extend.colors. Tout passe par du CSS pur via @theme inline. Au début ça surprend, au bout de 10 minutes on se demande pourquoi on a fait autrement pendant 4 ans.
Avant : l'enfer du config.js
En v3, pour ajouter une couleur de marque accent avec un support dark mode, il fallait : déclarer des CSS variables dans le CSS global, les référencer dans tailwind.config.js, compiler, prier pour que l'autocomplétion VS Code suive.
v4 : une seule source de vérité
Maintenant on déclare les variables dans :root, on les expose via @theme inline, et Tailwind génère automatiquement les utilitaires correspondants. Mon globals.css complet :
@import "tailwindcss";
:root {
--color-bg: #0A0A0B;
--color-accent: #58C4DC;
--color-text-primary: #EDEDED;
}
[data-theme="light"] {
--color-bg: #F7F7F5;
--color-accent: #087EA4;
--color-text-primary: #0A0A0B;
}
@theme inline {
--color-bg: var(--color-bg);
--color-accent: var(--color-accent);
--color-text-primary: var(--color-text-primary);
}Dans le code JSX, bg-bg, text-accent, border-text-primary marchent out of the box, avec autocomplétion VS Code (via l'extension Tailwind officielle).
Le truc qui m'a bloqué 20 minutes
Les noms d'utilitaires viennent du segment après --color-. Donc --color-text-primary devient text-text-primary - pas super élégant. Soit on vit avec, soit on raccourcit les tokens (ex: --color-fg → text-fg).
Dark mode : zéro JS
Un attribut data-theme="light" sur <html>, géré par next-themes, et toutes les variables basculent. Pas de dark: à rajouter partout - les variables font le boulot.
Verdict
Moins de config, plus de CSS natif, meilleure ergonomie. La migration d'un projet v3 → v4 prend ~1h sur un design system de taille moyenne. Je ne reviendrai pas en arrière.