2 points par GN⁺ 2026-01-21 | 4 commentaires | Partager sur WhatsApp
  • Bien que les boutons radio intégrés nativement aux navigateurs web soient de simples éléments HTML, la bibliothèque UI Shadcn les reconstruit en plusieurs couches de composants React
  • Les composants <RadioGroup> et <RadioGroupItem> de Shadcn encapsulent à nouveau des composants de Radix UI, tout en utilisant des icônes lucide-react et des dizaines de classes Tailwind
  • Radix s’appuie sur des attributs ARIA pour l’accessibilité et la personnalisation, mais réutilise en pratique des éléments bouton au lieu de l’élément natif <input type="radio">
  • Alors qu’un style identique peut être obtenu avec du simple CSS, cette structure ajoute des centaines de lignes de code et plusieurs dépendances, créant une complexité inutile
  • En ne réutilisant pas les éléments HTML natifs, cette approche accroît la dégradation des performances et la charge de maintenance, tout en nuisant à la simplicité du développement web

Analyse de la structure des boutons radio de Shadcn

  • Shadcn implémente les boutons radio via deux composants, <RadioGroup> et <RadioGroupItem>
    • Chaque composant encapsule des primitives importées depuis @radix-ui/react-radio-group et utilise CircleIcon de lucide-react
    • L’ensemble comprend plus de 45 lignes de code, 3 imports externes et un style défini avec plus de 30 classes Tailwind
  • La structure charge une bibliothèque d’icônes SVG pour afficher un simple indicateur circulaire
    • Une fonction qui pourrait être remplacée par border-radius en CSS ou un élément <circle>

Le rôle de Radix UI

  • Radix, utilisé par Shadcn, est une bibliothèque de composants UI bas niveau centrée sur l’accessibilité et la personnalisation
    • Son implémentation du groupe de boutons radio repose sur environ 215 lignes de code React et importe 7 fichiers
  • Radix configure un comportement de bouton radio en ajoutant des attributs ARIA à des éléments <button>
    • Pourtant, le premier principe de l’utilisation d’ARIA selon le W3C indique qu’il faut utiliser les éléments HTML natifs quand c’est possible
    • Radix ne suit pas ce principe et réutilise des boutons à la place d’un <input>
  • Il n’ajoute un <input type="radio"> masqué qu’à l’intérieur d’un <form>, ce qui manque de cohérence

Une alternative simple possible avec CSS

  • Les boutons radio HTML natifs peuvent être facilement stylisés avec appearance: none, ::before, :checked, border-radius, etc.
    • Le code d’exemple montre une personnalisation complète sans dépendances, sans JavaScript et sans attributs ARIA
    • Le même rendu peut aussi être obtenu avec Tailwind
  • L’idée selon laquelle « styliser des boutons radio est difficile » est un problème du passé ; aujourd’hui, le CSS pur offre un contrôle suffisant

Le problème de l’accumulation de complexité

  • Utiliser Shadcn avec Radix oblige à comprendre deux bibliothèques et des centaines de lignes de code
    • Pour un simple bouton radio, plusieurs kilo-octets de JavaScript sont chargés en plus
    • L’utilisateur doit attendre le parsing et l’exécution du JS pour pouvoir simplement basculer un bouton
  • Cette structure entraîne une hausse de la charge cognitive, une augmentation du risque de bugs et une dégradation des performances web

Retour à la simplicité

  • Les navigateurs fournissent déjà des boutons radio, et une seule ligne comme <input type="radio" name="beverage" value="coffee" /> suffit
  • Les abstractions inutiles et l’empilement de bibliothèques nuisent à la simplicité et à l’efficacité originelles du développement web
  • Même pour de petits éléments UI, une conception qui réutilise les fonctionnalités natives est plus avantageuse à la fois pour la maintenance et pour les performances

4 commentaires

 
slowandsnow 2026-01-22

Quand on voit le composant bouton de react aria, on manque de tomber dans les pommes lol

 
preserde 2026-01-21

Comme je travaille dans le frontend, c’est un problème auquel je suis confronté depuis longtemps, et, comment dire, c’est vraiment un problème difficile à résoudre. L’implémentation continue d’évoluer selon les époques, mais le fait de ne pas le résoudre avec input type reste le même, quelle que soit l’époque...
Essayer d’imiter le comportement des boutons radio et des cases à cocher du navigateur web en réimplémentant séparément les spécifications liées à l’accessibilité, franchement, je me demande bien à quoi ça rime... Je ne sais pas... Comme le dit l’article, il existe maintenant des alternatives en CSS, donc voir qu’on s’obstine malgré tout à vouloir l’implémenter en composant, c’en est presque drôle.

 
crawler 2026-01-21

Ennuyeux et pédant :

function RadioGroup({  
  className,  
  ...props  
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {  
  return (  
    <RadioGroupPrimitive.Root  
      data-slot="radio-group"  
      className={cn("grid gap-3", className)}  
      {...props}  
    />  
  );  
}  
...  

Réglé en un instant, facile à retenir longtemps :

<input type="radio" name="beverage" value="coffee" />  
 
GN⁺ 2026-01-21
Commentaires sur Hacker News
  • Je ne fais pas souvent du frontend, mais dès le moment où React est devenu dominant, on voyait déjà venir une montée de la complexité
    Les autres couches d’abstraction ont tendance à simplifier, mais React produit une abstraction bien plus complexe que les technologies sur lesquelles il repose
    J’ai l’impression que des développeurs qui ne connaissent que React empilent des couches toujours plus hautes, ce qui aboutit à des conceptions excessives

    • Je pense que le vrai problème aujourd’hui, c’est l’ambiance où tout le monde considère React comme le choix par défaut
      Par exemple, Shadcn ou Radix sont des bibliothèques UI réservées à React, mais à lire leur marketing, on pourrait croire à des bibliothèques UI généralistes
    • Cela fait plus de 15 ans que je crée des UI en JavaScript pur et avec les API du DOM
      À grande échelle, j’ai fini soit par construire mon propre framework, soit par être frustré par les frameworks existants, et React règle en partie ce problème
      Plus que React lui-même, c’est l’excès de complexité de son écosystème qui pose problème. Si on maîtrise bien React, cela reste agréable à utiliser
    • Je ne pense pas que ce soit seulement un problème de React : le vrai souci, c’est que les gens ne veulent pas apprendre le CSS moderne
      Ils cherchent juste à contourner le CSS avec des outils comme Tailwind. J’utilise React pour gérer l’état, mais je préfère faire le style directement en CSS
      Le plus difficile, c’est de convaincre les membres de l’équipe d’apprendre le CSS
    • Une abstraction devrait être à l’origine un outil philosophique pour masquer la complexité, mais aujourd’hui elle la rend souvent encore plus grande
      J’évite ces frameworks « modernes » et je préfère autant que possible les technologies de base
    • Le cœur de React, c’est l’abstraction par composants
      React ne fournit que des « boîtes », et c’est au développeur de décider quoi y mettre. C’est là sa vraie force
  • Cet exemple de bouton radio est à la fois drôle et frappant
    Le résultat final est indiscernable d’un simple bouton radio CSS natif, donc on peut se demander pourquoi le rendre aussi complexe
    Je me demande s’il existe des exemples de grands sites construits sans cette complexité inutile

    • Le site de McMaster-Carr est souvent cité comme bon exemple. Il y a aussi ce thread Hacker News
    • J’ai créé il y a 15 ans une web app de collaboration vidéo dont le frontend reposait presque entièrement sur une structure vanilla basée sur jQuery
      Il y avait plus de code qu’aujourd’hui, mais l’interface donnait une impression de réactivité immédiate
      Voir le code du projet Takeoff
    • « Et ce site-là ? » — au fond, Hacker News lui-même est peut-être un tel exemple
    • Plus une entreprise grandit, plus les managers veulent une stack standardisée
      Comme on dit, « personne ne s’est jamais fait virer pour avoir choisi React », donc c’est devenu l’option sûre
    • L’UI est visible par tout le monde et suscite beaucoup d’avis, donc la complexité y grossit comme une tragédie des biens communs
  • Les développeurs doivent se rappeler qu’ils peuvent toujours contester les exigences de design
    Un développeur perdait 4 heures sur un simple problème de layout en React Native ; on lui a dit de demander s’il était possible de modifier légèrement le design, et le problème a été réglé en 10 minutes

    • En ce moment, je préfère les frameworks UI sans JS (Pico.CSS, Skeleton, Bulma, Tailwind/daisyUI)
      Avec du CSS bien utilisé, on peut obtenir des résultats largement suffisants. Je serais curieux d’avoir les recommandations de ceux qui ont essayé cette approche
  • La plus grosse erreur de 2025 a été de choisir Shadcn
    Voir Radix importé en permanence a été un premier signal d’alerte, puis le composant radio a été le deuxième
    Le projet était déjà trop avancé pour faire marche arrière, donc j’ai bricolé avec Copilot, mais au final cette dépendance à l’IA ne m’a pas plu non plus
    Mon POC précédent était bien plus simple et efficace. Un jour, j’aimerais tout refaire en HTML vanilla

    • La combinaison React+NextJS+Tailwind+Shadcn, c’est le boss final de la complexité
      Remix ou React Router 7 faisaient encore au moins l’effort de rester proches des standards du web
      C’est avec Tailwind que je me suis dit « ça ne va pas », et si mes amis trouvent toujours ça bien après refactorisation, j’y reviendrai peut-être
    • En réalité, Tailwind et React ne vont pas si bien ensemble
      React a déjà un style basé sur les props, donc il n’y a pas vraiment de raison d’empiler des blocs de classes CSS
      Si l’objectif principal est l’accessibilité, Radix UI suffit largement
  • Le problème, c’est que les éléments <input> du navigateur, en particulier radio et select, sont difficiles à personnaliser
    Les boutons radio natifs ont une mauvaise ergonomie sur mobile

    • En réalité, même les contrôles natifs peuvent être suffisamment stylés avec du CSS
      J’aimerais comprendre plus précisément quels problèmes il y avait sur mobile
    • L’article explique justement comment styliser des boutons radio en CSS. Est-ce vraiment ça, le problème ?
    • En les enveloppant dans un <label> et en ajoutant du padding, cela reste tout à fait utilisable sur mobile
    • Pour les « select », le styling reste effectivement délicat, mais le reste peut être personnalisé de manière assez souple
  • La plupart des projets commencent avec de bonnes intentions, puis finissent un jour remplis d’un code de bouton radio sur 200 lignes et de 7 imports
    C’est ainsi que commence la dégradation du code (code rot)

  • J’ai récemment testé daisyUI et j’aime plutôt bien
    Comme c’est basé sur du pur CSS, cela exploite bien les nouvelles fonctionnalités du navigateur (comme dialog)

    • Mais côté accessibilité, il y a beaucoup de lacunes
      Par exemple, le Drawer ne piège pas le focus, et l’Accordion abuse des boutons radio comme substitut au JS
      C’est pour cela que des bibliothèques comme Radix finissent inévitablement par devenir complexes
  • Je suis d’accord avec l’idée générale du billet, mais je me demande si, pour reproduire à l’identique dans tous les navigateurs le style exact qu’un designer a créé dans Figma, le CSS vanilla suffit vraiment
    Peut-on recréer complètement quelque chose comme la démo de Radix ?

    • Avec quelques ajustements, on peut obtenir quelque chose d’assez proche
      Voir cet exemple CodePen
    • Au final, même sous ces frameworks complexes, le CSS reste l’élément central
      Il suffit d’extraire le CSS et de l’attacher à un simple composant React
    • Comme dans cet exemple, si on applique au vanilla input le même CSS, la compatibilité navigateur reste bonne
    • L’auteur de l’article est même intervenu pour dire qu’il s’agissait simplement d’adapter l’exemple de base au style Shadcn, et que tout peut être personnalisé autant qu’on veut
    • Mais la vraie question est jusqu’où poursuivre la perfection
      Est-ce que cela vaut vraiment la peine d’ajouter des dizaines de ko de code et une charge de maintenance juste pour éviter de légères différences visuelles ?
      Comme le disait Nam June Paik : « si c’est trop parfait, Dieu se met en colère »
  • Le vrai coût, ce n’est pas le code, mais le temps d’onboarding
    Pour qu’un nouveau développeur comprenne un bouton radio Radix de 47 lignes, il faut des semaines
    En version vanilla, on peut le faire en une journée et l’expliquer en 20 minutes
    Bien sûr, pour des produits comme Figma ou Linear, où l’accessibilité et la navigation au clavier sont essentielles, cette complexité se justifie

    • On peut quand même se demander si une bonne bibliothèque ne devrait pas pouvoir être utilisée sans avoir à connaître sa structure interne
  • Beaucoup de commentaires critiquent Shadcn, mais pour ma part je trouve au contraire qu’il encourage bien la structure des composants et la réutilisabilité
    Le principe central de Shadcn, c’est de dire : « possédez vos composants et modifiez-les vous-même »
    C’est une approche fondamentalement différente de celle des bibliothèques UI traditionnelles