12k
All articles

shadcn/ui ha cambiado de Radix a Base UI

shadcn/ui cambió los nuevos proyectos de Radix a Base UI. Mira qué cambia, quién no necesita migrar y el coste real del cambio.

OpenReplay Team
OpenReplay Team
shadcn/ui ha cambiado de Radix a Base UI

Si tu aplicación con shadcn/ui funciona sobre Radix, no necesitas migrar. Base UI es ahora la opción predeterminada para los nuevos proyectos, pero Radix sigue teniendo soporte completo, las actualizaciones se publican para ambas bibliotecas y el equipo de shadcn continúa usando Radix en sus propias aplicaciones en producción.

El cambio se produjo el 3 de julio de 2026. Buena parte de la cobertura posterior ha dado a entender que se avecina una reescritura, lo cual no es lo que dice el changelog.

Dos preguntas determinan qué hacer a continuación: si estás obligado a actuar y cuánto cuesta una migración si decides emprenderla. El coste se divide entre los cambios que el compilador detecta y los que no, y es en estos últimos donde reside el riesgo.

Puntos clave

  • Base UI es la opción predeterminada para los nuevos proyectos de shadcn/ui; Radix no está obsoleto, y -b radix mantiene Radix en una inicialización nueva.
  • Las aplicaciones existentes con Radix no requieren cambios: las actualizaciones se publican para ambas bibliotecas y el equipo de shadcn sigue usando Radix en producción.
  • El valor predeterminado cambió porque Base UI había alcanzado una versión estable 1.6.0 con más de seis millones de descargas semanales, y los usuarios de shadcn/create la elegían frente a Radix en una proporción de dos a uno.
  • Una migración se divide entre cambios que rompen la compilación (asChild a render, Positioner/Popup, valores nulables en Select) y cambios silenciosos de comportamiento (activación manual de pestañas, menús que permanecen abiertos), que son los que suponen el coste real.
  • Si migras, mantén ambas bibliotecas instaladas, mueve un componente por commit y utiliza la skill oficial de shadcn en lugar de un codemod.

Qué cambió el 3 de julio de 2026

Los nuevos proyectos de shadcn/ui ahora usan Base UI de forma predeterminada, y nada más cambió en los proyectos existentes. Se modificaron tres cosas. Ejecutar npx shadcn init selecciona Base UI salvo que indiques lo contrario, shadcn/create coloca Base UI en lo alto de su lista, y la documentación de componentes ahora te lleva a la pestaña de Base UI, con una pestaña de Radix junto a ella. Radix como tal no está obsoleto.

Mantener Radix en un proyecto nuevo requiere un solo flag:

pnpm dlx shadcn init -b radix

En cualquier punto donde CI o un script de scaffolding invoque shadcn init sin prompt y dé por hecho que obtendrá Radix, pasa ese flag ahora. El valor predeterminado bajo esos scripts ha cambiado.

¿Necesitas migrar a los componentes de shadcn con Base UI?

No. El changelog se compromete a publicar cada actualización y cada componente nuevo en ambas bibliotecas, con la única excepción de los componentes que existen en Base UI y no tienen equivalente en Radix. También indica que el propio código de producción del equipo sigue sobre Radix, sin planes de moverlo. Una aplicación estable con Radix no tiene plazos forzados, ni ventana de obsolescencia, ni un abismo de mantenimiento. El resto de este artículo está dirigido a los equipos que eligen migrar, no a los que deben hacerlo.

¿Por qué cambió el valor predeterminado?

El changelog da cuatro razones. La biblioteca había alcanzado una versión estable 1.6.0 y superaba los seis millones de descargas semanales. Sus mantenedores siguen añadiendo primitivas útiles. El equipo de shadcn ya la había estandarizado para todo lo nuevo. Y entre quienes crean proyectos con shadcn/create, Base UI ganaba aproximadamente dos elecciones por cada una que iba a Radix.

Esas cifras son las que se citan en el changelog. Base UI ha seguido publicando desde entonces: la versión 1.8.0 llegó el 4 de septiembre de 2026. El changelog también señala que Base UI proviene de las mismas personas que construyeron Radix. El paquete que hay que instalar es @base-ui/react; el nombre más antiguo, @base-ui-components/react, incluye un aviso de obsolescencia en npm que redirige a él.

Qué cambia realmente una migración

La mitad de la migración que rompe la compilación es mecánica: renombrados y cambios de tipos que el compilador detecta de inmediato.

RadixBase UI
asChild en los triggersprop render
Portal > ContentPortal > Positioner > Popup
OverlayBackdrop
variantes data-[state=open]:variantes data-open:
onOpenChange(open) + event.preventDefault()onOpenChange(open, details) + details.cancel()

Un matiz: la división Positioner/Popup se aplica a los popups anclados como Menu, Select, Popover y Tooltip. Dialog no tiene Positioner; es Dialog.Backdrop más Dialog.Popup.

El cambio en el callback tiene este aspecto:

// Radix: block closing via the event
onEscapeKeyDown={(event) => event.preventDefault()}

// Base UI: one callback, with a reason and a cancel()
onOpenChange={(open, details) => {
  if (details.reason === "escape-key") {
    details.cancel()
    return
  }
  setOpen(open)
}}

Los tipos de los valores también cambian. Un Select controlado ahora devuelve Value | null en lugar de una cadena, lo que convierte esto en la ruptura de compilación más habitual:

const [fruit, setFruit] = useState<string | null>(null)

Los valores de Accordion y Toggle Group son siempre arrays, incluso en modo de selección única, de modo que value="a" pasa a ser value={["a"]}.

Los cambios que compilan pero se comportan de otro modo

La mitad peligrosa de la migración supera la verificación de tipos sin problemas y aun así altera el comportamiento en tiempo de ejecución. Destacan tres diferencias:

  • Las pestañas se activan manualmente por defecto. Las teclas de flecha desplazan el foco entre los triggers sin cambiar el panel visible, salvo que definas activateOnFocus en Tabs.List, cuyo valor predeterminado es false. Radix usaba activación automática por defecto.
  • Los elementos checkbox y radio de los menús mantienen el menú abierto. closeOnClick tiene como valor predeterminado false en Menu.CheckboxItem y Menu.RadioItem, lo contrario del cierre al seleccionar de Radix. Un Menu.Item normal sigue teniendo true por defecto, así que el comportamiento varía según el tipo de elemento.
  • NavigationMenu se abre más rápido al pasar el cursor. El delay de Base UI tiene un valor predeterminado de 50 ms; el delayDuration de Radix es de 200 ms por defecto. Los menús por los que antes los usuarios pasaban de largo ahora se abren.

Nada de esto genera un error. Un menú que permanece abierto tras un clic y unas pestañas que ignoran las teclas de flecha son invisibles para la monitorización de errores, porque no se lanza ninguna excepción. El session replay es donde aflora esta clase de regresión: ves a un usuario pulsar una tecla de flecha, o hacer clic dos veces en un elemento checkbox, y observas que la interfaz no responde como espera.

¿Quién debería pasarse a Base UI y quién no?

Migra si necesitas Combobox, Autocomplete o Number Field, que Radix nunca llegó a ofrecer, o si quieres mantenerte alineado con los nuevos componentes del registry a medida que aparecen. Quédate en Radix si tu aplicación es estable y nada de esto te aplica; el compromiso de soporte es explícito, y una aplicación en producción que funciona no gana nada con un cambio de primitivas.

No bases la decisión en supuestas carencias de componentes. Base UI ofrece Context Menu, Toast y una primitiva de hover card con el nombre de Preview Card, y la documentación de Base UI de shadcn cubre las tres.

Cómo migrar si decides hacerlo

Usa la skill oficial, no un codemod, y avanza de forma progresiva. El razonamiento se sostiene. Un codemod solo conoce la versión original de un archivo, así que se apaña con los componentes que dejaste intactos y falla con los que modificaste. La skill lee lo que realmente tienes, traslada tus modificaciones e informa de las diferencias de comportamiento en lugar de reescribirlas en silencio.

pnpm dlx skills add shadcn/ui

Después pide a tu agente de código que migre un componente, por ejemplo migrate accordion to base-ui. Puedes mantener ambas bibliotecas instaladas a la vez, de modo que la build siga en verde entre pasos. Cada ejecución verifica los tipos de lo que ha producido, escribe una nota sobre ese componente en una carpeta .migration/ y lo deja como su propio commit en una rama que puedes descartar. Empieza por componentes hoja como button y label antes de abordar los componentes que los importan, y lee la sección de cambios de comportamiento de cada informe antes de hacer merge.

Una advertencia: algunas guías sugieren reapuntar components.json a Base UI y volver a añadir todos los componentes con --overwrite. Eso descarta todas las modificaciones locales que hayas hecho en esos archivos, que es precisamente el fallo que la skill existe para evitar.

En qué situación te deja esto

El valor predeterminado cambió; tus obligaciones no. Las aplicaciones existentes con Radix siguen funcionando, los proyectos nuevos usan Base UI salvo que pases -b radix, y una migración es un proyecto opcional cuyo coste visible son los renombrados y cuyo coste oculto es el comportamiento. Si migras, reserva tiempo de QA para las diferencias silenciosas, porque ahí es donde el compilador deja de ayudarte. Empieza por leer tú mismo la entrada del changelog y decide después si Combobox o la alineación con el registry justifican la rama.

Preguntas frecuentes

¿Está Base UI listo para producción en comparación con Radix?

Sí. Base UI publicó una versión estable 1.0.0 en diciembre de 2025 bajo el paquete '@base-ui/react' y ha lanzado versiones de forma constante desde entonces, alcanzando la 1.8.0 el 4 de septiembre de 2026. Procede de los creadores de Radix, Floating UI y Material UI, y su equipo afirma que diseñó la API para que se pareciera a la de Radix de forma deliberada, con el fin de que moverse entre ambas requiera menos trabajo. El equipo de shadcn también utiliza Base UI en todos los proyectos nuevos que inicia.

¿Todas las props de valor son arrays en Base UI?

No. El 'value' de Accordion es siempre un array y el 'value' de Toggle Group es siempre un array de cadenas, incluso en modo de selección única, pero el 'value' de Tabs sigue siendo un valor único con un valor predeterminado de 0, y Select está tipado como un valor único, un array o null. Envuelve los valores de Accordion y Toggle Group en arrays, tipa el estado controlado de Select como nulable y deja Tabs sin cambios.

¿Migrar a Base UI afecta a los componentes de shadcn que nunca usaron Radix?

No. Command envuelve cmdk, Sonner es una biblioteca de toasts independiente, Calendar utiliza react-day-picker, Input OTP usa input-otp y Charts se apoya en recharts. Ninguno de ellos depende de primitivas de Radix, así que una migración de Radix a Base UI los deja intactos. Solo los componentes cuyas primitivas provenían de Radix, como Dialog, Menu, Select, Tabs y Popover, necesitan cambios.

¿La skill de migración de shadcn requiere pnpm?

No. El changelog documenta la instalación de la skill para pnpm, npm, yarn y bun, de modo que 'npx skills add shadcn/ui' es un equivalente válido basado en npm del comando de pnpm. Tras la instalación, la skill se ejecuta a través de tu agente de código, que migra un componente cada vez y produce código con los tipos verificados, un informe por componente en el directorio '.migration' y un commit por componente, sea cual sea el gestor de paquetes.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.