- Embora o botão de opção já seja um elemento HTML simples embutido no navegador, a biblioteca de UI Shadcn o reconstrói em várias camadas de componentes React
- O
<RadioGroup> e o <RadioGroupItem> do Shadcn encapsulam novamente componentes do Radix UI e usam ícones do lucide-react junto com dezenas de classes do Tailwind
- O Radix usa atributos ARIA para acessibilidade e customização, mas na prática reutiliza elementos de botão em vez do
<input type="radio"> nativo
- Mesmo sendo possível obter o mesmo estilo com CSS simples, essa estrutura adiciona centenas de linhas de código e várias dependências, gerando complexidade desnecessária
- Ao não reutilizar elementos HTML nativos, aumentam a perda de desempenho e a carga de manutenção, comprometendo a simplicidade do desenvolvimento web
Análise da estrutura dos botões de opção no Shadcn
- O Shadcn implementa botões de opção por meio de dois componentes:
<RadioGroup> e <RadioGroupItem>
- Cada componente encapsula primitivas importadas de
@radix-ui/react-radio-group e usa o CircleIcon do lucide-react
- Há mais de 45 linhas de código, 3 imports externos e estilização com mais de 30 classes do Tailwind
- A estrutura chega a carregar uma biblioteca de ícones SVG apenas para exibir um simples círculo
- Algo que poderia ser substituído por
border-radius no CSS ou por um elemento <circle>
O papel do Radix UI
- O Radix usado pelo Shadcn é uma biblioteca de componentes de UI de baixo nível voltada para acessibilidade e customização
- A implementação do grupo de botões de opção no Radix tem cerca de 215 linhas de código React e importa 7 arquivos
- O Radix adiciona atributos ARIA ao elemento
<button> para fazê-lo se comportar como um botão de opção
- Porém, o primeiro princípio do uso de ARIA da W3C afirma que, sempre que possível, deve-se usar elementos HTML nativos
- O Radix não segue esse princípio e reutiliza botões no lugar de
<input>
- Dentro de
<form>, ele só adiciona um <input type="radio"> oculto, o que reduz a consistência da abordagem
Uma alternativa simples possível com CSS
- O botão de opção HTML nativo pode ser estilizado com facilidade usando
appearance: none, ::before, :checked, border-radius e outros recursos
- No código de exemplo, a customização completa é feita sem dependências, JavaScript ou atributos ARIA
- O mesmo efeito também pode ser implementado com Tailwind
- A percepção de que “estilizar botões de opção é difícil” é um problema do passado; hoje é possível ter controle suficiente apenas com CSS puro
O problema do acúmulo de complexidade
- Ao usar Shadcn junto com Radix, é preciso entender duas bibliotecas e centenas de linhas de código
- Para um único botão de opção simples, são carregados vários KB de JavaScript adicionais
- O usuário precisa esperar o parsing e a execução do JS apenas para alternar um botão
- Essa estrutura leva a mais carga cognitiva, maior possibilidade de bugs e pior desempenho na web
De volta à simplicidade
- O navegador já fornece botões de opção nativamente, e uma única linha como
<input type="radio" name="beverage" value="coffee" /> já basta
- Abstrações desnecessárias e o uso de bibliotecas em camadas prejudicam a simplicidade e a eficiência originais do desenvolvimento web
- Mesmo em pequenos elementos de UI, um design que reaproveita funcionalidades nativas é melhor tanto para manutenção quanto para desempenho
4 comentários
Entediante e pedante:
Termina rapidinho, fica na memória por muito tempo:
Se você olhar o componente de botão do React Aria, vai quase desmaiar kkk
Como alguém da área de frontend, é um problema que enfrento há muito tempo e, sinceramente, é um problema realmente difícil de resolver. A implementação continua mudando conforme a época, mas o fato de não resolverem isso com
input typeé igual em qualquer era... Tentar imitar o comportamento de botões de rádio e checkbox do navegador e ainda implementar separadamente as especificações de acessibilidade... afinal, qual é a ideia disso...? Não sei... Como o texto diz, hoje já existem alternativas até com CSS, então ver gente insistindo em implementar isso como componente a qualquer custo chega a ser meio engraçado.Comentários do Hacker News
Não trabalho com frontend com tanta frequência, mas desde a época em que o React virou mainstream já dava para ver sinais de aumento de complexidade
Outras camadas de abstração tendem a simplificar, mas o React acaba criando uma abstração muito mais complexa do que a tecnologia subjacente
Tenho a sensação de que desenvolvedores que só conhecem React vão empilhando camadas cada vez mais altas, o que leva a resultados excessivamente arquitetados
Por exemplo, Shadcn e Radix são bibliotecas de UI exclusivas para React, mas olhando só o marketing parecem bibliotecas de UI genéricas
Quando a escala cresce, no fim você acaba criando seu próprio framework ou ficando insatisfeito com os existentes, e o React resolve parte desse problema
Vejo o problema mais na complexidade excessiva do ecossistema do que no React em si. Se você souber usar React bem, ainda pode ser bem agradável
Só tentam contornar CSS com ferramentas como Tailwind. Eu gerencio estado com React, mas prefiro fazer o styling diretamente em CSS
A parte mais difícil é convencer o time a aprender CSS
Eu evito esses frameworks “modernos” e prefiro, sempre que possível, as tecnologias básicas
React só fornece a “caixa”, e o que vai dentro dela é decisão do desenvolvedor. Esse é o verdadeiro poder do React
Este exemplo de radio button é engraçado e impressionante ao mesmo tempo
O resultado final é indistinguível de um radio button com CSS básico, então fico me perguntando por que fazer algo tão complexo
Tenho curiosidade se existem exemplos de sites de grande escala feitos sem esse tipo de complexidade desnecessária
Tinha mais código do que hoje, mas a interface passava uma sensação de resposta imediata
Dá para ver no código do projeto Takeoff
Como diz o ditado, “ninguém foi demitido por escolher React”, então virou a opção segura
Desenvolvedores precisam lembrar que sempre podem contestar exigências de design
Eu vi um desenvolvedor desperdiçar 4 horas em um problema simples de layout no React Native; sugeri perguntar se o design podia mudar um pouco, e resolveu em 10 minutos
Só com CSS já dá para obter resultados muito bons. Queria saber se alguém aqui recomenda esse tipo de abordagem
O maior erro de 2025 foi ter escolhido Shadcn
Ver imports contínuos do Radix foi o primeiro alerta, e ver o componente de radio foi o segundo
Como o projeto já estava em andamento, acabei seguindo e ajustando tudo com Copilot, mas no fim também não gostei dessa dependência de IA
O POC anterior era muito mais simples e eficiente. Um dia quero refazer tudo em HTML vanilla
Remix e React Router 7 pelo menos tentavam se manter mais próximos dos padrões da web
Foi no Tailwind que pensei “isso não dá”, e se meus amigos continuarem dizendo que ficou bom depois da refatoração, talvez eu reveja isso
React já tem styling baseado em props, então não faz muito sentido usar blocos enormes de classes CSS
Se o foco for acessibilidade, só o Radix UI já basta
O problema é que o elemento
<input>do navegador, especialmente radio e select, é difícil de customizarO radio button padrão tem usabilidade ruim no mobile
Gostaria de entender com mais detalhe quais problemas você teve no mobile
<label>e adicionar padding, no mobile já fica bastante utilizávelA maioria dos projetos começa com boas intenções, mas em algum momento acaba cheia de radio buttons com 200 linhas de código e 7 imports
É assim que começa a deterioração do código (code rot)
Usei daisyUI recentemente e gostei bastante
Como é baseado em CSS puro, consegue aproveitar bem novos recursos do navegador (como
dialog)Por exemplo, o Drawer não faz focus trap, e o Accordion usa radio buttons de forma abusiva como substituto de JS
É por isso que bibliotecas como Radix inevitavelmente acabam ficando complexas
Concordo com a ideia central do texto, mas se o designer criou no Figma um estilo exato que precisa ficar idêntico em todos os navegadores, será que CSS vanilla dá conta?
Dá para reproduzir completamente algo como a demo do Radix?
Veja este exemplo no CodePen
Basta extrair o CSS e aplicá-lo a um componente React simples
Será que vale mesmo adicionar dezenas de KB de código e custo de manutenção só para evitar pequenas diferenças visuais?
Como no ditado de Nam June Paik, “se ficar perfeito demais, Deus fica bravo”
O custo real não é o código, e sim o tempo de onboarding
Para um desenvolvedor novo entender um radio button de 47 linhas baseado em Radix, podem ir semanas
Já uma abordagem vanilla dá para fazer em um dia e explicar em 20 minutos
Claro, se for um produto como Figma ou Linear, onde acessibilidade e navegação por teclado são cruciais, essa complexidade pode ser justificável
Muita gente critica o Shadcn, mas eu acho justamente que ele incentiva bem a estrutura de componentes e a reutilização
A essência do Shadcn é a filosofia de “possua e modifique seus próprios componentes”
Isso é uma abordagem fundamentalmente diferente das bibliotecas de UI tradicionais