Comme dans une phase de sélection, la question n'est pas de savoir quel pick est le plus fort dans l'absolu, mais quel pick gagne sur la carte que tu joues. En 2026, les Web Components tiennent ce rôle : excellents pour poser une base partageable, beaucoup moins adaptés pour porter à eux seuls toute une application face à React et Vue.

Le retour en grâce ne traduit pas une révolution technique. Il traduit surtout une lassitude face à la volatilité des stacks front-end et une envie de stabilité : viser le navigateur lui-même plutôt qu'une API de framework.
Le kit de base : une balise, une isolation, une porte d'entrée
Un Web Component repose sur trois briques. Les Custom Elements enregistrent une nouvelle balise avec customElements.define('product-card', ProductCard), après quoi <product-card> fonctionne sur n'importe quelle page. Le Shadow DOM isole le balisage et les styles internes du reste de la page, donc une classe .title dans la carte n'entre jamais en collision avec une classe du même nom ailleurs. Les slots laissent passer du contenu extérieur à l'intérieur de ce bloc isolé.
C'est simple sur le papier, et c'est ce qui fait la force du standard : le composant parle directement au navigateur.
Lit, le support qui rend le standard jouable
Coder en Custom Elements pur reste verbeux. Lit ajoute la réactivité et les templates déclaratifs au-dessus, sans virtual DOM.
Selon lit.dev, la bibliothèque pèse autour de 5 Ko une fois minifiée et compressée, ce qui garde le bundle petit et le chargement rapide. Au rendu, Lit ne touche que les parties dynamiques de l'interface, sans reconstruire un arbre virtuel pour le comparer au DOM.
Autre point clé : Lit isole les styles par défaut grâce au Shadow DOM. Comme l'explique lit.dev, les sélecteurs restent simples, les styles du composant n'affectent pas la page et la page n'affecte pas le composant. Pour un bouton, une carte, un badge ou un input maison, c'est exactement ce que tu veux.
Tout composant Lit reste un custom element natif interopérable. Selon lit.dev, il fonctionne partout où tu utilises du HTML, avec n'importe quel framework ou sans framework, ce qui en fait un choix naturel pour des composants partageables, des design systems ou des sites pensés pour durer.
Le premier paint sans attendre JavaScript
Le point faible historique des Web Components, c'était le rendu serveur. Sans JavaScript, pas de shadow root, donc pas de contenu peint tout de suite.
Le Declarative Shadow DOM corrige ça avec une balise <template shadowrootmode="open"> : tu embarques la shadow root directement dans le HTML, et le navigateur attache l'arbre fantôme pendant l'analyse, sans attendre JavaScript. Résultat : un premier paint plus propre sur les pages servies côté serveur.
En juillet 2026, ce mécanisme est pris en charge nativement dans les versions actuelles de Chrome, Edge, Firefox et Safari. Si tu vises des navigateurs récents, pas besoin de couche supplémentaire. Pour des navigateurs plus anciens, il faut encore prévoir un polyfill.
Le clutch : un seul composant pour toutes les équipes
Le vrai terrain de victoire, c'est le design system multi-framework.
Écris un bouton ou une carte en custom element natif, et des pages React, Vue, Svelte et HTML pur peuvent consommer exactement le même composant, parce que la cible est le navigateur lui-même, pas une API de framework. Tu stabilises ton roster visuel une fois, tu le déploies partout.
C'est pour ça que Lit, FAST ou Stencil reviennent dans les discussions : pas pour "tuer" React, mais pour construire une couche basse commune qui survit aux changements de meta applicative.
Là où ça se complique face à React et Vue
Pour le développement d'applications complètes, React et Vue gardent l'avantage sur l'état global et le data-binding profond. Les Web Components tiennent en production, surtout pour un système partagé, mais ils ne doivent pas être vus comme un paradigme applicatif à eux seuls.
L'intégration React s'est nettement améliorée. Avant React 19, l'incapacité de React à gérer les événements personnalisés et les propriétés complexes freinait l'adoption. Ce verrou est levé avec la prise en charge complète dans React 19, ce qui a relancé l'intérêt pour les bibliothèques agnostiques.
Il reste des frictions concrètes à connaître :
Les attributs HTML sont des chaînes de caractères. Si tu passes un objet ou un tableau avec une syntaxe de type <product-card data={obj}>, il est sérialisé en chaîne dans l'attribut au lieu d'être assigné comme propriété DOM. La correction passe par une assignation directe du type ref.current.data = obj, par le système de propriétés réactives de Lit, et souvent par une fine couche d'adaptation côté React.
Un custom element n'est pas intégré à un formulaire par défaut, contrairement à un <input> natif. Il faut passer par ElementInternals et attachInternals(), déclarer static formAssociated = true, puis remonter la valeur avec internals.setFormValue(value) pour exposer la valeur, gérer la validation et l'accessibilité.
Même avec Lit, l'expérience développeur reste moins clé en main que côté framework. L'état, la communication entre composants, le routage, l'hydratation, les tests, les conventions de style et la stratégie SSR : beaucoup de décisions sont à assembler à la carte.
Dernier mythe à jeter : les Web Components ne sont pas plus légers ou plus performants par nature. Le standard lui-même n'ajoute pas forcément beaucoup de poids, mais le coût final dépend du code embarqué, du nombre de composants, du rendu, du chargement et des bibliothèques autour. Les mêmes métriques restent à surveiller : LCP, INP et CLS.
La règle pour trancher dans ton projet
Joue Web Components + Lit si tu construis des briques partageables : boutons, cartes, modales, champs, tokens visuels consommés par plusieurs applications ou plusieurs frameworks. Joue React ou Vue pour le match complet : état applicatif, routage, formulaires complexes, data-binding profond, conventions d'équipe.
Avant de locker, lance trois tests concrets. Monte un composant Lit avec styles isolés et slot, consomme-le dans une page HTML pure et dans une application React 19 avec une propriété objet passée par ref, puis branche-le dans un vrai <form> avec ElementInternals et validation. Si ces trois tests sont propres et que ton chargement garde de bons LCP et INP, tu as ton design system. Le reste appartient au framework applicatif.