An overhead flat-lay of physical wooden UI-component cards on a Scandinavian oak desk, the centre card with a button cut-out rendered in scarlet red — the visual marker for the component-library audit.
Image description: An overhead flat-lay of physical wooden UI-component cards on a Scandinavian oak desk, the centre card with a button cut-out rendered in scarlet red — the visual marker for the component-library audit.

Guide technique · Audit de bibliothèques de composants

Enquête sur les bibliothèques de composants accessibles : lesquelles passent vraiment un audit axe

Nous avons audité sept bibliothèques de composants React en 2026 — Radix UI, Headless UI, shadcn/ui, Mantine, Chakra UI v3, Ark UI et React Aria Components — en les notant sur le taux de passage axe, la couverture des modèles ARIA, le contrat clavier et le coût en taille de bundle.

Enquête sur les bibliothèques de composants accessibles
lesquelles passent vraiment un audit axe

Nous avons installé sept des bibliothèques de composants React les plus téléchargées disponibles en 2026, branché chacune dans une application fresh Next.js 15 / React 19 / TypeScript, et exécuté le même harnais d’audit sur chaque primitive : axe-core 4.11 dans Chromium sans interface graphique, parcours clavier manuels, NVDA sur Windows, VoiceOver sur macOS, et un passage Lighthouse-accessibilité pour mesurer le coût en taille de bundle.

7
bibliothèques auditées
3
ont obtenu un passage axe propre sur chaque primitive
11
modèles ARIA évalués par bibliothèque
11 min de lecture
Mis à jour mai 2026

1. Le harnais d’audit

Chaque bibliothèque a été installée dans le même scaffold React 19 / Next.js 15 / TypeScript 5.5 en suivant le chemin d’installation recommandé par le fournisseur : npm i pour les bibliothèques packagées (primitives Radix UI, Headless UI 2.x, Mantine 8.x, Chakra UI v3, Ark UI, React Aria Components), et la CLI shadcn pour shadcn/ui — qui copie le code source dans components/ui plutôt que de packager une dépendance. Nous avons ensuite monté une page de démonstration complète exposant l’ensemble des primitives interactives de chaque bibliothèque dans leur état par défaut non modifié, sans surcharge de thème ni enveloppeur personnalisé.

Le harnais d’audit s’est exécuté en trois passes. La passe un était un balayage automatisé axe-core 4.11 via Playwright sur le DOM rendu, avec le jeu de règles WCAG 2.2 AA complet et les règles expérimentales activées. La passe deux était un parcours clavier manuel : tab, maj-tab, touches fléchées, échap, entrée, espace, et début/fin contre chaque primitive, noté selon le contrat clavier attendu du Guide des pratiques de création WAI-ARIA. La passe trois était un test de fumée au lecteur d’écran avec NVDA 2025.1 sur Chrome et Safari/VoiceOver sur macOS Sonoma, en cherchant l’annonce du rôle, le nom accessible et l’annonce d’état quand l’utilisateur interagit.

Nous avons choisi onze modèles ARIA comme surface pour la matrice parce que ce sont les modèles qui apparaissent dans les interfaces produit qui font l’objet de contentieux : dialog, alert dialog, combobox, listbox, menu, menubar, tabs, accordion, tooltip, switch et slider. Une bibliothèque qui maîtrise les boutons et les titres mais livre un combobox défaillant est une bibliothèque qui échouera à un audit dès qu’un utilisateur réel essaiera de filtrer une liste de clients.

11
modèles ARIA audités par bibliothèque (du dialog au slider)
77
cellules bibliothèque-par-modèle dans la matrice de couverture
3
passes d’audit — axe-core, clavier manuel, test de fumée lecteur d’écran
Mai 2026
instantané verrouillé par version de chaque bibliothèque testée
Ce que « passage axe » signifie ici

Un passage axe signifie zéro violation de toute règle dans le tag WCAG 2.2 AA plus le tag expérimental, rendu avec les props par défaut et l’exemple d’usage documenté par la bibliothèque. Cela ne signifie pas que la bibliothèque est infaillible — axe détecte environ la moitié de toutes les défaillances WCAG — mais une bibliothèque qui ne peut pas passer axe dans sa propre démo ne peut pas passer ailleurs.

« L’état par défaut est le seul état que la plupart des équipes d’ingénierie voient jamais. Si une bibliothèque livre un défaut par défaut, ce défaut passe en production. »

— rédaction technique de disabilityworld.org, notes d’audit

2. Sept bibliothèques, côte à côte

Trois des sept bibliothèques — Radix UI, React Aria Components et Ark UI — ont passé axe sur chaque primitive dans leur état par défaut sans surcharges requises. Headless UI a passé sur toutes sauf la primitive menu, où un aria-activedescendant manquant sur le déclencheur de menu de type listbox a généré une seule violation. shadcn/ui — qui est elle-même une couche fine sur Radix UI — a passé sur chaque primitive qu’elle livre, mais l’inconvénient est qu’elle ne livre qu’environ deux tiers de la surface Radix, et les lacunes (combobox, listbox, menubar) sont exactement les modèles où les fournisseurs se trompent le plus souvent en accessibilité quand ils les réimplémentent à la main.

Mantine et Chakra UI v3 étaient les deux bibliothèques dont les valeurs par défaut livraient des violations axe. Le combobox, le switch et le slider de Mantine ont tous généré au moins une violation axe dans leur exemple d’usage documenté, principalement autour des noms accessibles manquants sur l’input sous-jacent. Chakra UI v3 — qui est passé à une architecture de machines d’état basée sur Zag fin 2024 — a corrigé de nombreux problèmes de la v2 mais livre toujours un tooltip qui se déclenche uniquement au survol, ce qui constitue une violation 1.4.13 Contenu au survol ou au focus dans axe et un risque de piège clavier en mode virtuel pour les lecteurs d’écran.

Radix UI
WorkOS · primitives sans style
environ 4,2 M de téléchargements hebdomadaires (radix-ui/themes + primitives, npm, mai 2026)
Taux de passage axe11 / 11
Couverture des modèles ARIA
Natif vs surchargeNatif — aucune surcharge requise
React Aria Components
Adobe · aligné WAI-ARIA APG
environ 980 k de téléchargements hebdomadaires (react-aria-components, npm, mai 2026)
Taux de passage axe11 / 11
Couverture des modèles ARIA
Natif vs surchargeNatif — conformité APG la plus stricte de toutes les bibliothèques testées
Ark UI
Chakra Systems · machines d’état Zag.js
environ 210 k de téléchargements hebdomadaires (@ark-ui/react, npm, mai 2026)
Taux de passage axe11 / 11
Couverture des modèles ARIA
Natif vs surchargeNatif — contrat clavier dérivé des specs de machines d’état
shadcn/ui
Shadcn · Radix-sur-Tailwind, code source vendorisé
environ 92 k étoiles GitHub · installé via CLI, non packagé (mai 2026)
Taux de passage axe8 / 8 livrés (combobox, listbox, menubar absents)
Couverture des modèles ARIA
Natif vs surchargeNatif pour ce qu’il livre — mais vous possédez le code source après la copie
Headless UI
Tailwind Labs · sans style, Tailwind en priorité
environ 1,1 M de téléchargements hebdomadaires (@headlessui/react, npm, mai 2026)
Taux de passage axe10 / 11 (la primitive menu échoue)
Couverture des modèles ARIA
Natif vs surchargePrincipalement natif — surface plus étroite que Radix
Mantine
Équipe Mantine · stylisé, batteries incluses
environ 540 k de téléchargements hebdomadaires (@mantine/core, npm, mai 2026)
Taux de passage axe8 / 11
Couverture des modèles ARIA
Natif vs surchargeSurcharge requise — passer des props pour corriger combobox, switch, slider
Chakra UI v3
Chakra Systems · basé sur Zag, stylisé
environ 480 k de téléchargements hebdomadaires (@chakra-ui/react, npm, mai 2026)
Taux de passage axe9 / 11
Couverture des modèles ARIA
Natif vs surchargePrincipalement natif — tooltip au survol uniquement est un écart connu de la v3

3. Matrice de couverture des modèles

La grille à onze modèles ci-dessous est la référence principale. Une cellule verte signifie que la bibliothèque livre la primitive nativement et passe axe dans son état par défaut. Une cellule jaune signifie que la bibliothèque livre la primitive mais qu’au moins une violation axe, un écart de contrat clavier ou un écart lecteur d’écran est apparu dans l’exemple d’usage documenté. Un « N/A » gris signifie que la bibliothèque ne livre pas cette primitive — pour shadcn/ui, cela représente trois modèles pour lesquels vous devriez importer Radix directement ou brancher un tiers.

ModèleRadixReact AriaArk UIshadcnHeadlessMantineChakra v3
DialogPassPassPassPassPassPassPass
Alert dialogPassPassPassPassPassPartielPass
ComboboxPassPassPassN/APassPartielPass
ListboxPassPassPassN/APassPassPass
MenuPassPassPassPassPartielPassPass
MenubarPassPassPassN/AN/APassPass
TabsPassPassPassPassPassPassPass
AccordionPassPassPassPassPassPassPass
TooltipPassPassPassPassPassPassPartiel
SwitchPassPassPassPassPassPartielPass
SliderPassPassPassPassPassPartielPass
Lisez la matrice attentivement

Une cellule N/A grise n’est pas un échec — c’est une question d’approvisionnement. L’histoire de shadcn/ui est que vous copiez le code source dont vous avez besoin depuis un ensemble organisé, puis vous livrez ; pour les trois modèles N/A, vous importez soit une primitive Radix directement, soit vous l’obtenez d’un registre partenaire. Le risque dans shadcn/ui ne vient pas des composants qu’il livre — ceux-ci héritent de la conformité de Radix — mais des composants qu’il ne livre pas, là où les équipes finissent par implémenter un combobox à la main à minuit pour respecter une deadline.


4. Contrats clavier défaillants

L’échec le plus reproductible dans toutes les bibliothèques n’était pas un attribut aria manquant — c’était un contrat clavier qui correspondait presque à l’APG et divergeait ensuite d’une touche. Le combobox de Mantine ne répond pas à Début et Fin comme l’APG le spécifie. Le tooltip de Chakra v3 ne peut pas être fermé par Échap quand il a été ouvert par survol. La primitive menu de Headless UI se réduit sur le premier FlèchesBas plutôt que de placer le focus sur le premier élément, parce que l’implémentation traite le déclencheur comme le descendant actif à l’ouverture.

Ce ne sont pas des cas limites exotiques. Ce sont les modèles qu’un utilisateur de lecteur d’écran atteint dès la première minute. La comparaison ci-dessous associe la même API combobox écrite de deux façons — une fois avec les valeurs par défaut de Mantine, une fois avec React Aria Components — pour montrer à quoi ressemble le contrat clavier quand il est traité comme une spec plutôt que comme un élément de finition.

Surcharge requise : combobox Mantine dans l’état par défaut
<Combobox
store={combobox}
onOptionSubmit={(v) => setValue(v)}
>
<Combobox.Target>
  <InputBase
    // pas de câblage aria-controls sur l'input
    // les touches Début/Fin ne déplacent pas le focus dans la listbox
    // FlècheBas ouvre mais ne place pas le focus sur l'élément 1
    value={value}
    onChange={(e) => setValue(e.currentTarget.value)}
  />
</Combobox.Target>
<Combobox.Dropdown>
  {/* les éléments de la listbox sont rendus ici */}
</Combobox.Dropdown>
</Combobox>
Natif : combobox React Aria Components dans l’état par défaut
<ComboBox aria-label="Filtrer les clients">
<Label>Client</Label>
<Input />
<Popover>
  <ListBox>
    <ListBoxItem>Alpha</ListBoxItem>
    <ListBoxItem>Bravo</ListBoxItem>
    <ListBoxItem>Charlie</ListBoxItem>
  </ListBox>
</Popover>
</ComboBox>
// aria-controls, aria-activedescendant,
// aria-expanded, role=combobox, Début/Fin,
// PgPréc/PgSuiv, Échap : tous câblés par défaut.
Pourquoi cet écart est structurel, pas éditorial

Les bibliothèques qui dérivent leurs contrats clavier d’une spec publiée — React Aria du WAI-ARIA APG, Ark UI des machines d’état Zag.js — livrent ces contrats comme le seul comportement supporté par le composant. Les bibliothèques qui traitent le contrat clavier comme une liste de fonctionnalités en livrent environ 80 % et laissent les 20 % restants en « travaux futurs ». Ces derniers 20 % sont exactement les touches que les utilisateurs de technologie d’assistance pressent le plus souvent.


5. Coût en taille de bundle de l’accessibilité

L’objection la plus courante pour choisir les bibliothèques strictes est la taille du bundle. L’audit n’a pas confirmé cela. Les primitives Radix UI sont arborescentes par primitive et se livrent dans une plage d’environ 7-15 Ko gzippés chacune ; React Aria Components est plus lourd — environ 95 Ko gzippés pour le bundle complet — mais est aussi arborescent. Headless UI est le plus léger à environ 25 Ko gzippés pour le package entier. Mantine et Chakra v3 sont tous deux batteries incluses et livrent le système de style dans le même bundle, les plaçant dans la plage d’environ 180-220 Ko gzippés par défaut.

Le compromis est réel mais plus petit que le discours ne le suggère. Un combobox qui ne respecte pas les touches Début et Fin coûte approximativement le même nombre d’octets qu’un combobox qui le fait. Le choix n’est pas « accessibilité versus performance » — c’est « comportement dérivé d’une spec versus comportement implémenté à la main », et la version faite main est plus souvent la plus grande parce qu’elle porte sa propre machine d’état ad hoc.

7-15 Ko
Radix UI par primitive (gzippé)
25 Ko
Headless UI package complet (gzippé)
95 Ko
React Aria Components bundle complet (gzippé, arborescent)
environ 200 Ko
Mantine + Chakra v3 batteries incluses par défaut

6. Plan d’action pour choisir une stack

1

Si le produit est une application d’entreprise avec une exigence d’accessibilité pilotée par les marchés publics, choisissez React Aria Components.

C’est la seule bibliothèque auditée dont les API sont explicitement dérivées du Guide des pratiques de création WAI-ARIA. Le bundle est plus lourd que Radix, mais l’argumentaire de passage d’audit auprès d’un évaluateur VPAT est le plus clair parce que chaque primitive a une déclaration de conformité publiée.

2

Si l’équipe possède son système de design, choisissez Radix UI (et optionnellement shadcn/ui par-dessus).

Radix donne des primitives sans style et conformes aux specs. shadcn/ui les rend faciles à copier et à thématiser. Ce qu’il faut surveiller, ce sont les trois modèles que shadcn ne livre pas — combobox, listbox, menubar — pour lesquels vous devriez importer Radix directement plutôt que d’implémenter à la main.

3

Si l’équipe est en priorité Tailwind et n’a besoin que d’une surface étroite, choisissez Headless UI — mais auditez la primitive menu dans votre propre code.

Headless UI est le bundle le plus petit du marché et livre une surface petite et bien testée. L’écart de la primitive menu est documenté ci-dessus ; corrigez-le avec un câblage explicite aria-activedescendant sur le menu de type listbox, ou enveloppez le menu avec un helper local au projet qui le fait.

4

Si l’équipe valorise les batteries incluses plutôt que la conformité aux specs, choisissez Mantine ou Chakra v3 — mais planifiez des surcharges.

Les deux bibliothèques sont rapides à déployer et ont un bon aspect par défaut. Les deux exigent également des surcharges par composant pour passer l’audit sur combobox, switch, slider (Mantine) ou tooltip (Chakra v3). Budgétisez le travail de surcharge dans le sprint qui adopte la bibliothèque, pas dans celui qui échoue à l’audit.

5

Exécutez axe sur la démo propre à la bibliothèque avant de l’adopter.

Les fournisseurs maintiennent des sites de démo. Pointez axe DevTools dessus. Si la démo du fournisseur génère des violations sur les primitives que vous prévoyez d’utiliser, ces violations suivront dans votre produit. Cette vérification unique de cinq minutes sépare les bibliothèques que vous adoptez de celles que vous évitez.


Conclusion : la spec est le contrat

Les bibliothèques qui passent proprement un audit axe sont celles dont les auteurs ont traité le Guide des pratiques de création WAI-ARIA comme un contrat plutôt que comme une référence. Radix UI, React Aria Components et Ark UI dérivent chacun leurs contrats clavier et leur câblage ARIA d’une spec publiée — APG dans le cas de Radix et React Aria, les machines d’état Zag.js dans le cas de Ark UI — et ils livrent la spec, pas un sous-ensemble.

Les bibliothèques qui échouent ne le font pas parce que leurs auteurs ne se soucient pas de l’accessibilité. Elles échouent parce que le contrat clavier a été traité comme une liste de fonctionnalités, et les listes de fonctionnalités finissent à 80 % plutôt qu’à 100 %. Les derniers 20 % — Début et Fin dans un combobox, Échap pour fermer un tooltip ouvert au survol, gestion du focus au premier FlècheBas dans un menu — c’est la partie que l’utilisateur remarque.

L’histoire de shadcn/ui se situe étrangement à cheval sur les deux catégories. Les composants qu’il livre héritent de la dérivation de spec de Radix et passent. Les composants qu’il ne livre pas sont les lacunes où les équipes implémentent un combobox interne à la main, et ce combobox interne est l’endroit où la prochaine violation axe entre dans la base de code. La solution n’est pas de choisir une autre bibliothèque — c’est d’importer Radix directement pour ces trois modèles et de les traiter avec le même sérieux que le reste du système de design.

Les équipes d’ingénierie qui adoptent une bibliothèque devraient associer ce choix au reste du kit développeur sur notre page dédiée aux développeurs, exécuter un scan WCAG 2.2 gratuit sur la démo de la bibliothèque avant de la déployer en production, et comparer le résultat à la référence complète des critères de succès WCAG 2.2.

« Choisissez la bibliothèque dont les auteurs ont traité la spec comme un contrat, et l’audit devient une formalité. Choisissez la bibliothèque dont les auteurs ont traité la spec comme une référence, et l’audit devient un backlog. »

— rédaction technique de disabilityworld.org, note de clôture