2 puntos por GN⁺ 2026-01-21 | 4 comentarios | Compartir por WhatsApp
  • Aunque el botón de opción ya viene integrado de forma nativa en los navegadores web como un elemento HTML simple, la librería de UI de Shadcn lo reconstruye en varias capas de componentes de React
  • <RadioGroup> y <RadioGroupItem> de Shadcn vuelven a envolver componentes de Radix UI y usan íconos de lucide-react junto con decenas de clases de Tailwind
  • Radix usa atributos ARIA para accesibilidad y personalización, pero en la práctica reutiliza elementos de botón en lugar del <input type="radio"> nativo
  • Aunque el mismo estilo se puede lograr con CSS simple, esta estructura agrega cientos de líneas de código y varias dependencias, provocando una complejidad innecesaria
  • Al no reutilizar elementos HTML nativos, empeoran el rendimiento y la carga de mantenimiento, y se daña la simplicidad del desarrollo web

Análisis de la estructura del botón de opción en Shadcn

  • Shadcn implementa los botones de opción mediante dos componentes: <RadioGroup> y <RadioGroupItem>
    • Cada componente envuelve primitivas importadas desde @radix-ui/react-radio-group y usa CircleIcon de lucide-react
    • Incluye más de 45 líneas de código y 3 imports externos, con estilo definido mediante más de 30 clases de Tailwind
  • Se carga una librería de íconos SVG solo para mostrar un círculo simple
    • Es una función que podría reemplazarse con border-radius en CSS o con un elemento <circle>

El papel de Radix UI

  • Radix, usado por Shadcn, es una librería de componentes UI de bajo nivel enfocada en accesibilidad y personalización
    • La implementación del grupo de botones de opción en Radix tiene alrededor de 215 líneas de código React e importa 7 archivos
  • Radix configura los botones de opción para que funcionen como tales agregando atributos ARIA a elementos <button>
    • Sin embargo, el primer principio del uso de ARIA del W3C establece que “cuando sea posible, se deben usar elementos HTML nativos”
    • Radix no sigue este principio y reutiliza botones en lugar de <input>
  • Dentro de un <form>, la estructura añade un <input type="radio"> oculto solo en ese contexto, lo que reduce la consistencia

Una alternativa simple posible con CSS

  • Los botones de opción HTML nativos pueden estilizarse fácilmente con appearance: none, ::before, :checked, border-radius, etc.
    • En el código de ejemplo se logra una personalización completa sin dependencias, JavaScript ni atributos ARIA
    • El mismo efecto también puede implementarse con Tailwind
  • La idea de que “dar estilo a los botones de opción es difícil” es un problema del pasado; hoy CSS puro ofrece control suficiente

El problema de la acumulación de complejidad

  • Si se usan Shadcn y Radix juntos, hay que entender dos librerías y cientos de líneas de código
    • Para un solo botón de opción simple se cargan varios KB de JavaScript
    • El usuario debe esperar el parseo y la ejecución de JS solo para alternar un botón
  • Esta estructura termina generando más carga cognitiva, más posibilidades de errores y peor rendimiento web

Volver a la simplicidad

  • Los navegadores ya incluyen botones de opción por defecto, y una sola línea como <input type="radio" name="beverage" value="coffee" /> es suficiente
  • Las abstracciones innecesarias y el uso de librerías anidadas dañan la simplicidad y eficiencia originales del desarrollo web
  • Incluso en elementos pequeños de UI, un diseño que reutiliza funciones nativas favorece tanto el mantenimiento como el rendimiento

4 comentarios

 
crawler 2026-01-21

Aburrido y pedante:

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

Se termina rápido y se recuerda por mucho tiempo:

<input type="radio" name="beverage" value="coffee" />  
 
slowandsnow 2026-01-22

Si ves el componente de botón de React Aria, como que te desmayas jajaja

 
preserde 2026-01-21

Como trabajo en frontend, es un problema que he sufrido durante mucho tiempo y, cómo decirlo, de verdad es un problema muy difícil de resolver. La implementación ha seguido cambiando con el tiempo, pero el hecho de no resolverlo con input type sigue siendo igual en cualquier época...
¿Qué se supone que intentan hacer implementando por separado las especificaciones de accesibilidad solo para imitar el comportamiento de los botones de opción y casillas de verificación del navegador web?... No lo entiendo... Como dice el artículo, ahora también hay alternativas con CSS, así que resulta hasta un poco gracioso ver que insisten en implementarlo como componente pase lo que pase.

 
GN⁺ 2026-01-21
Opiniones de Hacker News
  • No trabajo en frontend tan seguido, pero desde el momento en que React se volvió dominante ya se veía venir un aumento en la complejidad
    Otras capas de abstracción tienden a simplificarse, pero React termina creando una abstracción mucho más compleja que la tecnología sobre la que se basa
    Siento que los desarrolladores que solo conocen React siguen apilando capas cada vez más altas, y eso termina produciendo resultados sobreingenierizados

    • Ahora el problema mayor es que todos dan por hecho que React es la opción por defecto
      Por ejemplo, Shadcn y Radix son librerías de UI exclusivas para React, pero por su marketing parecen librerías de UI generales
    • Llevo más de 15 años creando UI con JavaScript puro y la DOM API
      Cuando el proyecto crece, al final uno termina armando su propio framework o frustrándose con los existentes, y React sí resuelve ese problema hasta cierto punto
      Más que React en sí, el problema es la sobrecarga de complejidad del ecosistema. Si solo trabajas con React, todavía puede ser agradable de usar
    • No es un problema exclusivo de React; creo que el problema mayor es que la gente no quiere aprender CSS moderno
      Solo intentan esquivarlo con herramientas como Tailwind. Yo uso React para manejar el estado, pero prefiero hacer el estilo directamente con CSS
      Lo más difícil es convencer a mis compañeros de equipo de que aprendan CSS
    • La abstracción en esencia debería ser una herramienta filosófica para ocultar complejidad, pero hoy muchas veces hace lo contrario y la aumenta
      Yo evito estos frameworks “modernos” y prefiero las tecnologías base siempre que sea posible
    • El núcleo de React es la abstracción por componentes
      React solo te da una “caja”, y el desarrollador decide qué meter dentro. Ese es su verdadero poder
  • Este ejemplo del radio button da risa pero también impresiona
    El resultado final es indistinguible de un radio button básico con CSS, así que uno se pregunta por qué hacerlo tan complejo
    Me da curiosidad si existen sitios grandes construidos sin este tipo de complejidad innecesaria

    • El sitio de McMaster-Carr suele mencionarse como buen ejemplo. También hay un hilo relacionado en Hacker News
    • Hace 15 años hice una webapp colaborativa de video, y el frontend era casi una estructura vanilla basada en jQuery
      Tenía más líneas de código que ahora, pero la interfaz daba una sensación de respuesta inmediata
      Se puede ver el código del proyecto Takeoff
    • “¿Y este sitio qué tal?” — quizá el propio Hacker News sea un ejemplo de eso
    • Mientras más grande es la empresa, más quieren los gerentes un stack estandarizado
      Como dice el dicho, “nadie fue despedido por elegir React”, así que se volvió la opción segura
    • La UI es algo que todos ven y sobre lo que todos opinan, así que la complejidad crece como una tragedia de los comunes
  • Los desarrolladores deberían recordar que siempre pueden cuestionar los requisitos de diseño
    A un desarrollador que estaba perdiendo 4 horas en un problema simple de layout en React Native le dijeron que preguntara si se podía cambiar un poco el diseño, y se resolvió en 10 minutos

    • Últimamente prefiero los frameworks de UI sin JS (Pico.CSS, Skeleton, Bulma, Tailwind/daisyUI)
      Con puro CSS se pueden lograr resultados bastante buenos. Me da curiosidad qué recomiendan quienes ya hayan usado este enfoque
  • El mayor error de 2025 fue haber elegido Shadcn
    Ver que seguía importando Radix fue la primera alerta, y ver el componente radio fue la segunda
    Como el proyecto ya estaba avanzado, seguí adelante y lo corregí con Copilot, pero al final tampoco me gustó depender de la IA
    El POC anterior era mucho más simple y eficiente. Algún día me gustaría rehacerlo todo con HTML vanilla

    • La combinación React+NextJS+Tailwind+Shadcn es el nivel máximo de complejidad
      Remix o React Router 7 al menos intentaban mantenerse más cerca de los estándares web
      Con Tailwind fue cuando pensé “esto ya no va”, y si mis amigos siguen diciendo que está bien después de refactorizar, entonces lo volveré a mirar
    • En realidad Tailwind y React no encajan tan bien
      React ya tiene estilo basado en props, así que no hay mucha razón para usar bloques enormes de clases CSS
      Si tu prioridad es la accesibilidad, con Radix UI basta
  • El problema es que los elementos <input> del navegador, sobre todo radio y select, son difíciles de personalizar
    Los radio buttons por defecto tienen mala usabilidad en móvil

    • En realidad los controles nativos también se pueden estilizar bastante bien con CSS
      Me gustaría saber más concretamente qué problema hubo en móvil
    • El artículo también explica cómo personalizar radio buttons con CSS. ¿Ese es el problema?
    • Si lo envuelves con <label> y le das padding, en móvil sigue siendo perfectamente usable
    • El “select” sí sigue siendo complicado de estilizar, pero el resto se puede personalizar con bastante flexibilidad
  • La mayoría de los proyectos empiezan con buenas intenciones, pero tarde o temprano terminan llenos de código de radio button de 200 líneas y 7 imports
    Así es como empieza la putrefacción del código (code rot)

  • Hace poco probé daisyUI y me gustó bastante
    Como está basado en CSS puro, puede aprovechar bien las nuevas funciones del navegador (como dialog)

    • Pero en accesibilidad se queda corto en varios puntos
      Por ejemplo, Drawer no logra atrapar el foco, y Accordion abusa de los radio buttons como reemplazo de JS
      Por eso librerías como Radix inevitablemente terminan siendo complejas
  • Estoy de acuerdo con la idea central del artículo, pero si quieres implementar en todos los navegadores el estilo exacto que hizo un diseñador en Figma, me pregunto si eso realmente es posible con CSS vanilla
    ¿Se puede reproducir por completo algo como la demo de Radix?

    • Con unos pequeños ajustes se puede lograr algo bastante parecido
      Se puede ver en este ejemplo de CodePen
    • Al final, incluso debajo de esos frameworks complejos, CSS sigue siendo lo esencial
      Basta con extraer el CSS y aplicarlo a un componente simple de React
    • Este ejemplo muestra que si aplicas el mismo CSS a un input vanilla, la compatibilidad entre navegadores también es buena
    • El propio autor apareció para aclarar que “solo adaptó el ejemplo básico al estilo de Shadcn, y que si uno quiere, se puede personalizar todo lo que quiera
    • Pero queda la duda de hasta qué punto vale la pena perseguir la perfección
      ¿De verdad tiene sentido agregar decenas de KB de código y carga de mantenimiento solo para evitar pequeñas diferencias visuales?
      Como decía Nam June Paik: “si es demasiado perfecto, Dios se enoja”
  • El costo real no está en el código, sino en el tiempo de onboarding
    A un desarrollador nuevo le puede tomar semanas entender un radio button de 47 líneas basado en Radix
    En cambio, la versión vanilla se hace en un día y se explica en 20 minutos
    Claro, si estás construyendo un producto como Figma o Linear, donde la accesibilidad y la navegación por teclado son importantes, esa complejidad sí se justifica

    • Queda la duda de si una buena librería no debería poder usarse sin necesidad de entender toda su estructura interna
  • Muchos comentarios critican a Shadcn, pero yo más bien creo que fomenta bien la estructura de componentes y la reutilización
    La esencia de Shadcn es la idea de “posee tus componentes y modifícalos tú mismo”
    Ese es un enfoque radicalmente distinto al de las librerías de UI tradicionales