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.

Guía de ingeniería · Auditoría de bibliotecas de componentes

Encuesta sobre bibliotecas de componentes accesibles: cuáles superan realmente una auditoría axe

Auditamos siete bibliotecas de componentes React en 2026 — Radix UI, Headless UI, shadcn/ui, Mantine, Chakra UI v3, Ark UI y React Aria Components — evaluando cada una en tasa de aprobación axe, cobertura de patrones ARIA, contrato de teclado y coste en tamaño de bundle.

Encuesta sobre bibliotecas de componentes accesibles
cuáles superan realmente una auditoría axe

Instalamos siete de las bibliotecas de componentes React más descargadas en 2026, conectamos cada una a una aplicación nueva de Next.js 15 / React 19 / TypeScript y ejecutamos el mismo conjunto de pruebas de auditoría contra cada primitivo: axe-core 4.11 en Chromium sin cabeza, comprobaciones manuales de teclado, NVDA en Windows, VoiceOver en macOS y un análisis de accesibilidad de Lighthouse para el coste en tamaño de bundle.

7
bibliotecas auditadas
3
obtuvieron una aprobación axe limpia en todos los primitivos
11
patrones ARIA evaluados por biblioteca
11 min de lectura
Actualizado mayo 2026

1. El conjunto de pruebas de auditoría

Cada biblioteca se instaló en el mismo andamiaje de React 19 / Next.js 15 / TypeScript 5.5 siguiendo la ruta de instalación recomendada por el proveedor: npm i para las bibliotecas empaquetadas (Radix UI primitives, Headless UI 2.x, Mantine 8.x, Chakra UI v3, Ark UI, React Aria Components), y la CLI de shadcn para shadcn/ui — que copia el código fuente en components/ui en lugar de empaquetarlo. A continuación, montamos una página de demostración completa que exponía el conjunto completo de primitivos interactivos de cada biblioteca en su estado predeterminado, sin modificaciones de tema y sin envoltorios personalizados.

El conjunto de pruebas de auditoría se ejecutó en tres pasadas. La primera fue un análisis automatizado axe-core 4.11 mediante Playwright contra el DOM renderizado, con el conjunto completo de reglas WCAG 2.2 AA y las reglas experimentales habilitadas. La segunda fue una comprobación manual de teclado: tabulador, tabulador+mayúsculas, teclas de flecha, escape, intro, espacio e inicio/fin contra cada primitivo, puntuada conforme al contrato de teclado esperado según la Guía de Prácticas de Autoría WAI-ARIA. La tercera fue una prueba de humo con lector de pantalla con NVDA 2025.1 en Chrome y Safari/VoiceOver en macOS Sonoma, evaluando el anuncio de rol, el nombre accesible y el anuncio de estado al interactuar el usuario.

Se seleccionaron once patrones ARIA como superficie de evaluación para la matriz, porque son los patrones que aparecen en las interfaces de producto que generan demandas: diálogo, diálogo de alerta, combobox, listbox, menú, barra de menú, pestañas, acordeón, información emergente (tooltip), interruptor (switch) y control deslizante (slider). Una biblioteca que domina los botones y los encabezados pero entrega un combobox roto es una biblioteca que fallará una auditoría en cuanto un usuario real intente filtrar una lista de clientes.

11
patrones ARIA auditados por biblioteca (de diálogo a control deslizante)
77
celdas biblioteca-por-patrón en la matriz de cobertura
3
pasadas de auditoría — axe-core, teclado manual, lector de pantalla
Mayo 2026
instantánea con versión fija de cada biblioteca probada
Qué significa «aprobación axe» aquí

Una aprobación axe significa cero infracciones de cualquier regla en la etiqueta WCAG 2.2 AA más la etiqueta experimental, renderizado con las props predeterminadas y el ejemplo de uso documentado por la biblioteca. No significa que la biblioteca sea infalible — axe detecta aproximadamente la mitad de todos los fallos WCAG — pero una biblioteca que no puede superar axe en su propia demo no puede superarlo en ningún otro lugar.

«El estado predeterminado es el único estado que la mayoría de los equipos de ingeniería ve nunca. Si una biblioteca entrega un valor predeterminado roto, ese valor predeterminado roto llega a producción.»

— Equipo de ingeniería de disabilityworld.org, notas de auditoría

2. Siete bibliotecas, lado a lado

Tres de las siete bibliotecas — Radix UI, React Aria Components y Ark UI — superaron axe en todos los primitivos en su estado predeterminado sin necesidad de modificaciones. Headless UI superó axe en todos salvo el primitivo de menú, donde un aria-activedescendant faltante en el disparador de menú de estilo listbox generó una única infracción. shadcn/ui — que es en sí misma una capa fina sobre Radix UI — superó axe en todos los primitivos que ofrece, pero la salvedad es que solo ofrece aproximadamente dos tercios de la superficie de Radix, y las lagunas (combobox, listbox, barra de menú) son exactamente los patrones en los que los equipos cometen más errores de accesibilidad cuando los implementan a mano.

Mantine y Chakra UI v3 fueron las dos bibliotecas cuyos valores predeterminados generaron infracciones en axe. El combobox, el switch y el slider de Mantine generaron al menos una infracción axe en su ejemplo de uso documentado, principalmente por nombres accesibles faltantes en el input subyacente. Chakra UI v3 — que adoptó una arquitectura de máquinas de estado basada en Zag a finales de 2024 — corrigió muchos de los problemas de v2, pero sigue entregando un tooltip que se activa solo al pasar el cursor, lo que constituye una infracción de 1.4.13 Contenido en suspensión o en foco en axe y un riesgo de trampa de teclado en el modo virtual del lector de pantalla.

Radix UI
WorkOS · primitivos sin estilos
aprox. 4,2 millones de descargas semanales (radix-ui/themes + primitives, npm, mayo 2026)
Tasa de aprobación axe11 / 11
Cobertura de patrones ARIA
Nativo vs. modificaciónNativo — sin modificaciones necesarias
React Aria Components
Adobe · alineado con WAI-ARIA APG
aprox. 980.000 descargas semanales (react-aria-components, npm, mayo 2026)
Tasa de aprobación axe11 / 11
Cobertura de patrones ARIA
Nativo vs. modificaciónNativo — la conformidad APG más estricta de todas las bibliotecas probadas
Ark UI
Chakra Systems · máquinas de estado Zag.js
aprox. 210.000 descargas semanales (@ark-ui/react, npm, mayo 2026)
Tasa de aprobación axe11 / 11
Cobertura de patrones ARIA
Nativo vs. modificaciónNativo — contrato de teclado derivado de especificaciones de máquinas de estado
shadcn/ui
Shadcn · Radix sobre Tailwind, código fuente incluido
aprox. 92.000 estrellas en GitHub · instalado por CLI, no empaquetado (mayo 2026)
Tasa de aprobación axe8 / 8 disponibles (combobox, listbox, barra de menú ausentes)
Cobertura de patrones ARIA
Nativo vs. modificaciónNativo para lo que ofrece — pero el código fuente pasa a ser responsabilidad propia tras la copia
Headless UI
Tailwind Labs · sin estilos, orientado a Tailwind
aprox. 1,1 millones de descargas semanales (@headlessui/react, npm, mayo 2026)
Tasa de aprobación axe10 / 11 (el primitivo de menú falla)
Cobertura de patrones ARIA
Nativo vs. modificaciónMayoritariamente nativo — superficie más estrecha que Radix
Mantine
Equipo de Mantine · con estilos, con todo incluido
aprox. 540.000 descargas semanales (@mantine/core, npm, mayo 2026)
Tasa de aprobación axe8 / 11
Cobertura de patrones ARIA
Nativo vs. modificaciónRequiere modificación — pasar props para corregir combobox, switch y slider
Chakra UI v3
Chakra Systems · basado en Zag, con estilos
aprox. 480.000 descargas semanales (@chakra-ui/react, npm, mayo 2026)
Tasa de aprobación axe9 / 11
Cobertura de patrones ARIA
Nativo vs. modificaciónMayoritariamente nativo — el tooltip de solo cursor es una laguna conocida en v3

3. Matriz de cobertura de patrones

La cuadrícula de once patrones que se muestra a continuación es la referencia principal. Una celda verde significa que la biblioteca incluye el primitivo de forma nativa y supera axe en su estado predeterminado. Una celda amarilla significa que la biblioteca incluye el primitivo, pero al menos una infracción axe, una laguna en el contrato de teclado o una laguna en el lector de pantalla aparecieron en el ejemplo de uso documentado. Una celda gris «N/A» significa que la biblioteca no incluye ese primitivo — en el caso de shadcn/ui, son tres patrones para los que habría que importar Radix directamente o conectar un componente externo.

PatrónRadixReact AriaArk UIshadcnHeadlessMantineChakra v3
DiálogoAprobadoAprobadoAprobadoAprobadoAprobadoAprobadoAprobado
Diálogo de alertaAprobadoAprobadoAprobadoAprobadoAprobadoParcialAprobado
ComboboxAprobadoAprobadoAprobadoN/AAprobadoParcialAprobado
ListboxAprobadoAprobadoAprobadoN/AAprobadoAprobadoAprobado
MenúAprobadoAprobadoAprobadoAprobadoParcialAprobadoAprobado
Barra de menúAprobadoAprobadoAprobadoN/AN/AAprobadoAprobado
PestañasAprobadoAprobadoAprobadoAprobadoAprobadoAprobadoAprobado
AcordeónAprobadoAprobadoAprobadoAprobadoAprobadoAprobadoAprobado
TooltipAprobadoAprobadoAprobadoAprobadoAprobadoAprobadoParcial
SwitchAprobadoAprobadoAprobadoAprobadoAprobadoParcialAprobado
SliderAprobadoAprobadoAprobadoAprobadoAprobadoParcialAprobado
Leer la matriz con atención

Una celda gris N/A no es un fallo — es una cuestión de aprovisionamiento. La propuesta de shadcn/ui consiste en copiar el código fuente que se necesita de un conjunto curado y entregarlo; para los tres patrones N/A, se puede importar un primitivo de Radix directamente o extraerlo de un registro hermano. El riesgo en shadcn/ui no son los componentes que sí incluye — esos heredan la conformidad de Radix — sino los que no incluye, donde los equipos acaban implementando un combobox propio a deshoras para cumplir un plazo.


4. Contratos de teclado que fallaron

El fallo más repetible entre las bibliotecas no fue un atributo ARIA faltante — fue un contrato de teclado que casi coincidía con la guía APG y luego divergía en una tecla. El combobox de Mantine no responde a Inicio y Fin como especifica la APG. El tooltip de Chakra v3 no puede cerrarse con Escape cuando se abrió al pasar el cursor. El primitivo de menú de Headless UI se contrae en la primera pulsación de Flecha abajo en lugar de situar el foco en el primer elemento, porque la implementación trata el disparador como el descendiente activo al abrirse.

Estos no son casos extremos exóticos. Son los patrones que un usuario de lector de pantalla alcanza en el primer minuto. La comparación siguiente muestra la misma API de combobox escrita de dos formas — una con los valores predeterminados de Mantine y otra con React Aria Components — para ilustrar cómo es el contrato de teclado cuando se trata como una especificación y no como un elemento de acabado.

Requiere modificación: combobox de Mantine en estado predeterminado
<Combobox
store={combobox}
onOptionSubmit={(v) => setValue(v)}
>
<Combobox.Target>
  <InputBase
    // sin conexión aria-controls en el input
    // las teclas Inicio/Fin no mueven el foco dentro del listbox
    // Flecha abajo abre pero no sitúa el foco en el elemento 1
    value={value}
    onChange={(e) => setValue(e.currentTarget.value)}
  />
</Combobox.Target>
<Combobox.Dropdown>
  {/* los elementos del listbox se renderizan aquí */}
</Combobox.Dropdown>
</Combobox>
Nativo: combobox de React Aria Components en estado predeterminado
<ComboBox aria-label="Filter customers">
<Label>Customer</Label>
<Input />
<Popover>
  <ListBox>
    <ListBoxItem>Alpha</ListBoxItem>
    <ListBoxItem>Bravo</ListBoxItem>
    <ListBoxItem>Charlie</ListBoxItem>
  </ListBox>
</Popover>
</ComboBox>
// aria-controls, aria-activedescendant,
// aria-expanded, role=combobox, Home/End,
// PageUp/PageDown, Escape: all wired by default.
Por qué esta brecha es estructural, no editorial

Las bibliotecas que derivan sus contratos de teclado de una especificación publicada — React Aria a partir de la WAI-ARIA APG, Ark UI a partir de las máquinas de estado de Zag.js — ofrecen esos contratos como el único comportamiento que admite el componente. Las bibliotecas que tratan el contrato de teclado como una lista de características entregan aproximadamente el 80 % de él y dejan el último 20 % como «trabajo futuro». Ese último 20 % es exactamente el conjunto de teclas que los usuarios de tecnología de apoyo presionan con más frecuencia.


5. Coste en tamaño de bundle por la accesibilidad

La objeción más habitual para elegir las bibliotecas más estrictas es el tamaño del bundle. La auditoría no lo confirmó. Los primitivos de Radix UI son descartables por árbol (tree-shakeable) por primitivo y se sitúan en el rango de aprox. 7-15 KB comprimido con gzip por unidad; React Aria Components es más pesado — aprox. 95 KB comprimido con gzip para el bundle completo — pero también es descartable por árbol. Headless UI es el más ligero con aprox. 25 KB comprimido con gzip para el paquete completo. Mantine y Chakra v3 son ambas soluciones con todo incluido e incluyen el sistema de estilos en el mismo bundle, situándolas en el rango de aprox. 180-220 KB comprimido con gzip de base.

La compensación es real pero menor de lo que sugiere el debate habitual. Un combobox que no respeta Inicio y Fin cuesta aproximadamente los mismos bytes que uno que sí lo hace. La elección no es «accesibilidad frente a rendimiento» — es «comportamiento derivado de la especificación frente a comportamiento implementado a mano», y la versión implementada a mano es con más frecuencia la más grande, porque lleva su propia máquina de estado ad hoc.

7-15 KB
Radix UI por primitivo (comprimido con gzip)
25 KB
Headless UI paquete completo (comprimido con gzip)
95 KB
React Aria Components bundle completo (comprimido con gzip, descartable por árbol)
aprox. 200 KB
Mantine + Chakra v3 solución con todo incluido por defecto

6. Guía para elegir el stack

1

Si el producto es una aplicación empresarial con un requisito de accesibilidad impuesto por la contratación, elegir React Aria Components.

Es la única biblioteca auditada cuyas APIs están explícitamente derivadas de la Guía de Prácticas de Autoría WAI-ARIA. El bundle es más pesado que Radix, pero la argumentación ante un revisor de VPAT es la más sencilla porque cada primitivo tiene una declaración de conformidad publicada.

2

Si el equipo es dueño de su propio sistema de diseño, elegir Radix UI (y opcionalmente shadcn/ui sobre él).

Radix proporciona primitivos sin estilos y conformes con la especificación. shadcn/ui facilita copiarlos e incorporar el tema. Hay que vigilar los tres patrones que shadcn no incluye — combobox, listbox, barra de menú — para los que se debería importar Radix directamente en lugar de implementarlos a mano.

3

Si el equipo trabaja principalmente con Tailwind y solo necesita una superficie reducida, elegir Headless UI — pero auditar el primitivo de menú en el propio código.

Headless UI es el bundle más pequeño del grupo y ofrece una superficie pequeña y bien probada. La única laguna en el primitivo de menú está documentada arriba; se puede corregir con una conexión explícita de aria-activedescendant en el menú de estilo listbox, o envolver el menú en un ayudante local del proyecto que lo haga.

4

Si el equipo valora tener todo incluido sobre la conformidad con la especificación, elegir Mantine o Chakra v3 — pero planificar las modificaciones.

Ambas bibliotecas permiten entregas rápidas y tienen buen aspecto de serie. Ambas también requieren modificaciones por componente para superar la auditoría en combobox, switch, slider (Mantine) o tooltip (Chakra v3). Hay que presupuestar el trabajo de modificación en el sprint de adopción de la biblioteca, no en el sprint en que se falla la auditoría.

5

Ejecutar axe contra la propia demo de la biblioteca antes de adoptarla.

Los proveedores mantienen sitios de demostración. Apuntar axe DevTools a ellos. Si la propia demo del proveedor genera infracciones en los primitivos que se planea utilizar, esas infracciones seguirán al producto. Esta única verificación de cinco minutos separa las bibliotecas que se adoptan de las que se evitan.


Conclusión: la especificación es el contrato

Las bibliotecas que superan una auditoría axe de forma limpia son aquellas cuyos autores trataron la Guía de Prácticas de Autoría WAI-ARIA como un contrato y no como una referencia. Radix UI, React Aria Components y Ark UI derivan cada una sus contratos de teclado y su conexión ARIA de una especificación publicada — la APG en el caso de Radix y React Aria, las máquinas de estado de Zag.js en el caso de Ark UI — y ofrecen la especificación completa, no un subconjunto de ella.

Las bibliotecas que fallan no lo hacen porque sus autores no se preocupen por la accesibilidad. Fallan porque el contrato de teclado fue tratado como una lista de características, y las listas de características acaban al 80 % en lugar del 100 %. El último 20 % — Inicio y Fin en un combobox, Escape para cerrar un tooltip abierto al pasar el cursor, gestión del foco en la primera pulsación de Flecha abajo en un menú — es la parte que nota el usuario.

La situación de shadcn/ui se sitúa de manera peculiar entre ambas categorías. Los componentes que ofrece heredan la derivación de la especificación de Radix y la superan. Los componentes que no ofrece son las lagunas donde los equipos implementan un combobox propio, y ese combobox propio es donde entra en la base de código la siguiente infracción axe. La solución no es elegir una biblioteca diferente — es importar Radix directamente para esos tres patrones y tratarlos con la misma seriedad que el resto del sistema de diseño.

Los equipos de ingeniería que adoptan una biblioteca deberían combinar la elección con el resto del kit de herramientas para desarrolladores en nuestra página de aterrizaje para desarrolladores, ejecutar un análisis gratuito de WCAG 2.2 en la demo de la biblioteca antes de llevarla a producción, y comparar el resultado con la referencia completa de criterios de conformidad WCAG 2.2.

«Elegir la biblioteca cuyos autores trataron la especificación como un contrato convierte la auditoría en un trámite. Elegir la biblioteca cuyos autores trataron la especificación como una referencia convierte la auditoría en un backlog.»

— Equipo de ingeniería de disabilityworld.org, nota de cierre