Passer du CSS-in-JS en temps de exécution aux composants serveur et aux styles en temps de compilation
Pourquoi l’utilisation de CSS-in-JS en temps d’exécution entre en conflit avec les composants serveur de React et les objectifs de performance, comment Tailwind, CSS Modules et les bibliothèques sans temps d’exécution se comparent, ainsi que comment effectuer une migration en toute sécurité.
Sources: Why CSS-in-JS Is Dying in 2026: Performance, Server Components, and What to Use Instead
Pendant plusieurs années, des bibliothèques CSS-in-JS en temps de exécution telles que styled-components et Emotion ont été la méthode privilégiée pour styliser les composants React : des styles limités à un composant, des valeurs déterminées par des props, et aucune collision de noms de classes globaux. Depuis, l’écosystème s’est tourné vers des styles générés au moment de la compilation, principalement sous l’effet des contraintes de performance et des React Server Components. Cet article explique ce qui a changé, compare les principales alternatives et vous propose une règle pratique pour savoir quand migrer un code existant et quand le laisser tel quel.
De nombreuses équipes, qu’elles soient grandes ou petites, ont déjà abandonné le stylage en temps de exécution pour de nouveaux projets, et les raisons sont importantes avant de choisir une approche.
Le coût de la génération de styles dans le navigateur
Les bibliothèques CSS-in-JS en temps de exécution génèrent du CSS pendant que votre application est en cours d’exécution. Lorsque les composants sont rendus, la bibliothèque transforme les définitions de style (y compris toutes les valeurs dépendant des props) en règles CSS, crée des noms de classe et insère des balises <style> dans le document. Ces opérations s’effectuent sur le thread principal, sur le dispositif de l’utilisateur. Des benchmarks publiés comparant ce système au CSS statique ont indiqué des ralentissements de rendu allant de 20 à 50 % ; l’impact réel dépend fortement de l’application, il convient donc d’utiliser ces chiffres comme indicateur pour mesurer ses propres pages plutôt que comme une valeur universelle.
Le problème de fond est d’ordre architectural et non lié à une erreur dans une bibliothèque en particulier : le calcul des styles s’effectue dans le navigateur plutôt qu’à l’étape de compilation. Cela signifie que le moteur de stylisation est inclus dans votre bundle JavaScript, ce qui oblige le navigateur à analyser et exécuter davantage de scripts avant que la page ne devienne interactive, et l’insertion des styles concurrence le rendu pour les ressources temporelles.
Pourquoi les composants serveur ont révélé cette faiblesse
Les React Server Components (RSC) s’affichent sur le serveur et envoient leur résultat au navigateur sans inclure le code du composant sous forme de JavaScript client. Le CSS-in-JS en temps de exécution dépend d’un environnement JavaScript qui suit et injecte les styles pendant le rendu, et il repose sur le contexte React, que les composants serveur ne prennent pas en charge. Cela le met en conflit avec le modèle axé sur le serveur utilisé par des frameworks tels que Next.js App Router.
Dans la pratique, l’utilisation de styled-components ou d’Emotion avec les composants serveur signifie que les parties stylisées de votre arborescence doivent être marquées comme des composants client à l’aide de la directive 'use client', généralement accompagnée d’une configuration supplémentaire pour collecter les styles lors du rendu serveur. Lorsque des primitives stylisées sont utilisées partout, une grande partie de l’arborescence des composants se retrouve du côté client. Cela annule en grande partie les avantages offerts par les composants serveur, à savoir moins de JavaScript envoyé au navigateur et moins de travail à y effectuer, simplement pour maintenir la bibliothèque de stylisation fonctionnelle. Pour de nombreuses équipes, cet échange n’en vaut pas la peine.
Les alternatives en temps de compilation
Le CSS-in-JS en temps d’exécution a connu son apogée entre 2018 et 2023. Aujourd’hui, il existe plusieurs solutions matures qui évitent ces coûts en temps d’exécution, chacune adaptée aux préférences différentes des équipes.
Tailwind CSS comme choix par défaut courant
Tailwind CSS est devenu le point de départ habituel pour les nouveaux projets React et Next.js. Vous composez des classes utilitaires directement dans le markup, et l’étape de compilation ne génère que le CSS des classes que vous utilisez réellement. Il n’y a pas de moteur de stylisation en temps de exécution, le fichier CSS résultant reste compact, et comme la sortie est du CSS pur, il fonctionne dans les composants serveur sans aucun traitement spécial.
Les modules CSS pour les équipes préférant du CSS pur
Si vous préférez écrire du CSS classique plutôt que des classes utilitaires, les modules CSS vous offrent des noms de classes à portée locale sans aucun coût en temps de exécution. Ils sont pris en charge nativement par la plupart des outils de bundling et des chaînes d’outils de framework, donc leur adoption ne nécessite généralement aucune configuration.
CSS-in-JS sans temps de exécution pour le modèle de création familier
Des bibliothèques telles que Panda CSS et Vanilla Extract vous permettent de continuer à écrire des styles en JavaScript ou TypeScript, tout comme avec styled-components, mais elles extraitent tout en CSS statique lors de la compilation. Vous conservez l’expérience de création et la sécurité des types, sans surcharge en temps de exécution, tout en bénéficiant d’une compatibilité totale avec les Server Components. L’adaptation principale consiste à ce que les styles soient analysables statiquement ; par conséquent, les valeurs qui changent en temps de exécution sont généralement exprimées via des variants ou des propriétés personnalisées CSS plutôt que par des props arbitraires. Les modèles permettant de relier les valeurs JavaScript aux variables CSS sont abordés dans notre guide sur les propriétés personnalisées CSS en temps de exécution.
Décider du moment de migrer
Nouveaux projets
Pour un nouveau projet, il y a peu de raisons de choisir CSS-in-JS à exécution au jour d’aujourd’hui. Une option raisonnable par défaut :
- Tailwind CSS pour la plupart des projets.
- CSS Modules si l’équipe préfère des feuilles de style conventionnelles.
- Une bibliothèque CSS-in-JS à exécution nulle si vous souhaitez continuer à écrire des styles en TypeScript sans avoir à payer pour une exécution.
Projets existants
Pour une application déjà construite avec styled-components ou Emotion, il n’y a pas besoin de se précipiter. Ces deux bibliothèques fonctionnent toujours bien dans les applications rendues côté client. La migration devient intéressante à planifier lorsque vous envisagez d’adopter les Server Components ou lorsque l’analyse des performances montre que le stylisme représente une part importante du coût de rendu.
Lorsque vous migrez, faites-le de manière progressive, composant par composant, en passant à Tailwind ou CSS Modules. Les composants simples et les primitives partagées comme les boutons constituent de bons points de départ. Les deux systèmes peuvent coexister pendant la transition, mais veillez à la spécificité et à l’ordre des styles lorsque les anciens et les nouveaux styles coexistent.
En résumé
- Le CSS-in-JS en temps de exécution a résolu des problèmes réels, mais il calcule les styles côté client, ce qui augmente la taille du bundle et consomme du temps sur le thread principal.
- Les composants serveur rendent ces coûts plus visibles, car les bibliothèques dépendent du JavaScript côté client et renvoient des arbres stylisés au client.
- Tailwind CSS, CSS Modules ainsi que des bibliothèques sans exécution en temps de exécution comme Panda CSS et Vanilla Extract génèrent tous du CSS statique au moment de la compilation et fonctionnent naturellement avec les composants serveur.