Shopping cart

Subtotal $0.00

View cartCheckout

Building better devs

TnewsTnews
  • Home
  • Programação
  • shadcn/ui Trocou o Radix pelo Base UI: O Que Muda no Seu Projeto React
Programação

shadcn/ui Trocou o Radix pelo Base UI: O Que Muda no Seu Projeto React

Email : 5

O shadcn/ui acabou de mudar de lado

Se você trabalha com React e já usou o shadcn/ui (e convenhamos, quem não usou?), prepare-se: a partir de julho de 2026, o Base UI é o padrão. Não o Radix. O Base UI.

Eu sei, parece aquele tipo de mudança silenciosa que só vai te afetar quando você rodar npx shadcn init num projeto novo e perceber que algo está diferente. Mas a real é que essa decisão reflete uma mudança maior no ecossistema React, e ignorar isso pode te custar horas de debugging no futuro.

Vamos entender o que aconteceu, por que aconteceu, e o que você precisa (ou não) fazer agora.

O que mudou, na prática

Quando você roda npx shadcn init agora, o Base UI vem selecionado por padrão. A documentação oficial abre na aba do Base UI. O shadcn/create mostra Base UI primeiro na interface.

Parece cosmético, certo? Só que não.

Essa mudança de padrão sinaliza para onde o ecossistema está indo. Quando a biblioteca de componentes mais popular do React escolhe um novo motor por baixo, todo o ecossistema sente.

Aqui está o resumo rápido:

O que mudou Antes Agora
Padrão no shadcn init Radix UI Base UI
Documentação padrão Aba Radix Aba Base UI
shadcn/create Radix primeiro Base UI primeiro
Suporte ao Radix Total Total (não mudou)

O ponto mais importante: o Radix não foi descontinuado. A equipe do shadcn deixou isso explícito. Todo componente novo e toda atualização serão lançados para ambas as bibliotecas. Se você tem um projeto rodando com Radix, ele continua funcionando normalmente.

Por que o Base UI ganhou esse espaço

A pergunta que todo mundo faz: por que trocar algo que funciona?

Três razões ficam claras quando você olha os números e o contexto:

1. Manutenção ativa e previsível

O Base UI é mantido pela MUI, que tem engenheiros, designers e gerentes dedicados ao projeto em tempo integral. Quando o Radix foi adquirido, rolou uma incerteza na comunidade sobre o futuro da manutenção. O Base UI, por outro lado, chegou na versão 1.6.0 com mais de 6 milhões de downloads semanais e um ritmo constante de releases.

Isso importa mais do que parece. Quando você escolhe uma biblioteca de primitivos para um projeto que vai durar anos, a pergunta não é “funciona hoje?”, mas sim “vai ter alguém corrigindo bugs daqui a 18 meses?”.

2. API mais limpa para casos complexos

Quem já tentou implementar um combobox com multi-select no Radix sabe a dor. O Base UI resolve esses casos com APIs que foram desenhadas pensando em composição complexa desde o início. Menus aninhados, comboboxes com filtragem, selects múltiplos: tudo funciona com menos código e menos workarounds.

3. A comunidade já tinha escolhido

Segundo dados do shadcn/create, projetos novos já estavam escolhendo Base UI sobre Radix numa proporção de 2 para 1. A equipe do shadcn basicamente formalizou o que a comunidade já estava fazendo.

Base UI vs Radix: as diferenças técnicas que importam

Vamos ao que interessa. Se você está decidindo entre os dois (ou pensando em migrar), estas são as diferenças que realmente impactam o dia a dia:

Arquitetura de pacotes

O Radix usa um modelo de pacotes separados: @radix-ui/react-dialog, @radix-ui/react-dropdown-menu, @radix-ui/react-tooltip… cada primitivo é um pacote independente. Isso parece bom na teoria (instale só o que usa), mas na prática cria uma árvore de dependências enorme com muitas dependências cruzadas entre pacotes.

O Base UI adota o modelo de pacote único: @base-ui/react. Tudo vem junto, mas as ferramentas modernas de build (tree-shaking) removem automaticamente o que você não importa. O resultado final é um bundle de tamanho similar ou até menor.


# Radix: múltiplos pacotes
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-tooltip @radix-ui/react-select

# Base UI: pacote único
npm install @base-ui/react

Bundle size

Os números são mais próximos do que você imagina:

Métrica Radix UI Base UI
Tamanho minificado (total) 443 KB 463 KB
Tamanho gzipped ~130 KB ~140 KB
Por componente (com tree-shaking) Similar Similar

A diferença de ~20 KB no total bruto não significa nada na prática, porque ninguém importa todos os componentes. Com tree-shaking, o custo por componente fica praticamente idêntico.

Posicionamento de elementos

Aqui tem uma diferença arquitetural importante. O Radix usa seu próprio sistema de posicionamento interno para popovers, tooltips e dropdowns. O Base UI usa o Floating UI (a evolução do Popper.js).

Se você já usa Floating UI no seu projeto para algum posicionamento customizado, o Base UI vai se integrar naturalmente. Se não, é mais uma dependência, mas que resolve posicionamento de forma mais robusta e configurável.

A prop asChild sumiu

Essa é a mudança que mais vai aparecer na migração. No Radix, asChild permite que o componente renderize como filho ao invés de criar um elemento wrapper:


// Radix: usa asChild
<Dialog.Trigger asChild>
  <button className="custom-btn">Abrir</button>
</Dialog.Trigger>

// Base UI: usa render prop
<Dialog.Trigger render={<button className="custom-btn">Abrir</button>} />

O Base UI substituiu asChild por render props, que dão mais controle sobre o que é renderizado. Se você tem asChild espalhado pelo projeto, vai precisar atualizar cada ocorrência.

Migrar ou não migrar: o guia honesto

Vou ser direto: se seu projeto está funcionando com Radix, não migre só porque mudou o padrão.

A equipe do shadcn foi clara: “Radix é uma biblioteca madura e testada. Nós ainda rodamos ela em produção e não estamos migrando.” Se até eles não estão migrando projetos existentes, por que você migraria?

Quando faz sentido migrar

  • Você está batendo em limitações do Radix (combobox complexo, multi-select, menus aninhados)
  • Seu projeto já usa Floating UI e quer unificar a stack
  • Você quer APIs mais modernas para componentes novos
  • Seu time está começando componentes do zero e prefere a API do Base UI

Quando NÃO faz sentido migrar

  • Seu projeto está estável e sem bugs relacionados ao Radix
  • Você tem dezenas de componentes customizados em cima do Radix
  • O time não tem bandwidth para testar a migração
  • Você está perto de um release importante

Se decidir migrar: o caminho progressivo

O shadcn criou uma ferramenta de migração baseada em “skills” que permite migrar componente por componente:


# Adicionar a skill de migração
pnpm dlx skills add shadcn/ui

# Migrar um componente específico
# O skill gera um relatório em .migration/ com as mudanças
# Cria commits limpos no git, um por componente
# Permite rollback fácil deletando a branch

A abordagem recomendada:

  1. Comece pelos componentes atômicos (Button, Badge, Input)
  2. Suba para componentes compostos (Dialog, Dropdown, Select)
  3. Termine com componentes de negócio que estendem APIs originais
  4. Rode testes de regressão global no final

O ponto chave: ambas as bibliotecas coexistem durante a transição. Você pode ter metade dos componentes em Radix e metade em Base UI sem conflito.

Mudanças de API que vão te pegar

Se você vai migrar (ou começar um projeto novo com Base UI), preste atenção nestas diferenças:

Checkbox

O Radix aceita "indeterminate" como string no estado. O Base UI exige boolean estrito e usa um parâmetro separado indeterminate:


// Radix
<Checkbox checked="indeterminate" />

// Base UI
<Checkbox checked={false} indeterminate={true} />

ToggleGroup

No Radix, value pode ser uma string. No Base UI, precisa ser array, e o campo multiple é explícito:


// Radix
<ToggleGroup type="multiple" value="bold">

// Base UI
<ToggleGroup value={["bold"]} multiple>

Form

A recomendação é migrar para o componente Field do Base UI, que tem uma API diferente do Form do Radix. Esse é provavelmente o componente mais trabalhoso de migrar se você tem formulários complexos.

Benchmark rápido: criando um Dialog nos dois

Para quem aprende melhor vendo código, aqui vai a mesma funcionalidade implementada nas duas bibliotecas. Um dialog simples com título, descrição e botão de fechar:

Com Radix (via shadcn):


import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"

export function MeuDialog() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <button>Abrir dialog</button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Confirmar ação</DialogTitle>
          <DialogDescription>
            Tem certeza que deseja continuar?
          </DialogDescription>
        </DialogHeader>
        <button>Confirmar</button>
      </DialogContent>
    </Dialog>
  )
}

Com Base UI (via shadcn):


import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"

export function MeuDialog() {
  return (
    <Dialog>
      <DialogTrigger render={<button>Abrir dialog</button>} />
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Confirmar ação</DialogTitle>
          <DialogDescription>
            Tem certeza que deseja continuar?
          </DialogDescription>
        </DialogHeader>
        <button>Confirmar</button>
      </DialogContent>
    </Dialog>
  )
}

Percebeu? A diferença é mínima na superfície. O asChild virou render, e o resto ficou praticamente igual. Essa é a mágica da camada de abstração do shadcn: a troca de motor por baixo não explode o código do consumidor.

Agora, se você estiver construindo componentes mais complexos, como um Select com busca e multi-seleção, aí a diferença fica mais visível. O Base UI oferece hooks como useSelect e useCombobox que simplificam bastante a lógica interna sem precisar de hacks ou bibliotecas auxiliares.

O que isso significa para o ecossistema React

Essa mudança do shadcn não acontece no vácuo. Ela reflete uma tendência maior: o ecossistema React está consolidando em torno de menos bibliotecas, mais bem mantidas.

Pensa assim: em 2023, a resposta para “qual biblioteca de componentes headless uso?” era “depende”. Tinha Radix, Headless UI, React Aria, Ark UI, Base UI… cada uma com trade-offs diferentes. Em 2026, o mercado convergiu. O Base UI, com o backing da MUI e a adoção pelo shadcn, se posicionou como a escolha padrão.

Isso não mata o Radix. Projetos existentes vão continuar rodando por anos. Mas novos projetos, novas contratações, novos tutoriais: tudo vai gravitar em torno do Base UI. E quando o ecossistema de tutoriais e Stack Overflow muda, o custo de manter a opção alternativa sobe silenciosamente.

Para projetos novos: checklist rápido

Se você está começando um projeto React do zero hoje, aqui vai o setup recomendado:


# Iniciar com shadcn/ui + Base UI (agora é o padrão)
npx shadcn init

# Se por algum motivo quiser Radix, force explicitamente
npx shadcn init -b radix

Se você tem scripts de CI rodando shadcn init de forma não interativa e esperando Radix, adicione -b radix para manter o comportamento anterior. Isso evita surpresas no pipeline.

Para o components.json, a mudança é no campo style:


{
  "style": "base-ui",
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "app/globals.css"
  }
}

A lição por trás da mudança

Toda vez que uma ferramenta popular troca de dependência interna, a comunidade entra em pânico. “Vou ter que reescrever tudo?” Quase nunca. O shadcn fez isso da forma certa: mudou o padrão para novos projetos, manteve suporte total ao antigo, e criou ferramentas de migração progressiva.

Se tem algo para levar desse episódio, é isso: bibliotecas headless são a camada de infraestrutura da UI moderna. Quando a infra muda, o impacto pode ser mínimo (se a abstração foi bem feita) ou catastrófico (se você acoplou seu código à implementação interna). O shadcn/ui funciona como essa camada de abstração, e é por isso que a troca de Radix para Base UI por baixo não quebra seu código.

Quem apostou em copiar e colar componentes Radix direto no projeto, sem a camada do shadcn, vai ter mais trabalho. Quem usou o shadcn como interface, só precisa atualizar quando quiser.

E se você está se perguntando “devo aprender Base UI agora?”: se trabalha com React profissionalmente, sim. Não porque o Radix vai morrer amanhã, mas porque os próximos 3 anos de conteúdo, exemplos e bibliotecas do ecossistema vão assumir Base UI como padrão. Melhor surfar a onda do que correr atrás dela.

FAQ rápido para quem está sem tempo

Meu projeto com Radix vai quebrar?

Não. O suporte ao Radix continua. Nenhuma atualização do shadcn vai remover componentes Radix.

Preciso migrar agora?

Não. Só migre se tiver uma razão técnica concreta (limitações do Radix, unificação de stack, etc).

Posso misturar Radix e Base UI no mesmo projeto?

Sim. A migração progressiva permite exatamente isso. Componentes de ambas as bibliotecas coexistem sem conflito.

O bundle fica maior com Base UI?

Na prática, não. Com tree-shaking, o tamanho por componente é equivalente. A diferença bruta de ~20 KB no pacote total desaparece quando o bundler remove o código não utilizado.

E se eu estiver começando um projeto hoje?

Vá de Base UI. É o padrão, tem manutenção ativa pela MUI, e todo o ecossistema está convergindo nessa direção. Você estará alinhado com a documentação, os tutoriais e o tooling mais recente.

O Radix vai ser descontinuado?

Não há indicação disso. A equipe do shadcn reforçou que ainda roda Radix em produção. Porém, a tendência de adoção está clara, e isso pode mudar o cenário de longo prazo.


Fonte de inspiração: shadcn/ui Changelog: Base UI as the Default

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts