UI SDK vs Base UI vs Radix: ¿qué biblioteca headless elegir para componentes estilo shadcn?
UI SDK de Vercel, Base UI y Radix comparados para componentes estilo shadcn: modelo, frameworks, cobertura, estilos, animación, beta, licencia y agentes.
Preet Suthar · · 9 min de lectura
- React
- UI SDK
- Base UI
- Radix
Hasta esta semana, elegir la capa de primitivas bajo una biblioteca de componentes estilo shadcn/ui significaba elegir entre dos opciones: Radix y Base UI. El 12 de noviembre de 2026, Vercel Labs publicó una tercera, UI SDK, como 0.1.0-beta.1. Es headless como las otras dos, pero se basa en otra idea y trae algo que ninguna de ellas tiene: un puente que permite a los agentes de IA leer y operar los componentes.
Una aclaración antes de la comparación. Los componentes de HextaUI están hechos hoy sobre Base UI, y estoy añadiendo una variante separada sobre UI SDK junto a ella. Tengo motivos para que me gusten ambas, así que he intentado ser justo, y cada afirmación de abajo viene de la documentación de las bibliotecas, de sus metadatos de npm o de una app de prueba donde construí el mismo componente tres veces.
Si quieres la migración de Radix a Base UI en detalle, con cada cambio de API en código de shadcn/ui, lee primero shadcn/ui se pasó a Base UI. Este post no la repite. Añade UI SDK al panorama y se pregunta desde cuál empezar.
La respuesta corta
- Elige Radix si tienes un código base de Radix que funciona, tu equipo lo conoce y no necesitas un componente que le falte. Es estable, solo para React y MIT.
- Elige Base UI para un nuevo design system en React que quieras publicar con APIs estables este trimestre. Es la opción por defecto en los proyectos nuevos de shadcn/ui, cubre más componentes que Radix y usa el modelo de atributos hacia el que se mueve la mayor parte del ecosistema.
- Elige UI SDK si necesitas algo más que React, quieres componentes como Color Picker, Date Picker o Tree sin una segunda biblioteca, o quieres que agentes de IA operen tu UI con herramientas estructuradas. Acepta que es una beta.
El resto del post es la evidencia.
Las tres de un vistazo
| Radix | Base UI | UI SDK | |
|---|---|---|---|
| Paquete | radix-ui 1.8.1 | @base-ui/react 1.9.0 | @ui-sdk/react 0.1.0-beta.1 |
| Licencia | MIT | MIT | Apache-2.0 |
| Estado | Estable | Estable | Beta |
| Frameworks | React | React | React, Vue, Svelte, Solid, Web Components |
| Estado abierto | data-state="open" | data-open | data-open |
| Entrada y salida | Keyframes sobre data-state | data-starting-style, data-ending-style | data-starting-style, data-ending-style |
data-slot en las partes | No | No | Sí |
| Partes del popup | Portal, Content | Portal, Positioner, Popup | Contenido en la top layer |
| Puente para agentes | No | No | Sí, con WebMCP |
Las tres son sin estilos y se encargan por ti del foco, el teclado y ARIA. Las versiones comparadas son las últimas en npm a 13 de noviembre de 2026: radix-ui 1.8.1 (publicada el 12 de octubre de 2026), @base-ui/react 1.9.0 (9 de octubre de 2026) y @ui-sdk/react 0.1.0-beta.1 (12 de noviembre de 2026).
Tres modelos distintos
Radix publica una primitiva por componente. Un paquete Dialog te da Root, Trigger, Portal, Overlay, Content, Title, Description y Close, y esa es la unidad con la que trabajas. Los comportamientos de dentro, como atrapar el foco o cerrar, son internos. El paquete radix-ui los agrupa todos.
Base UI tiene la misma forma: un componente, varias partes. Añade más utilidades públicas a su alrededor, como useRender y mergeProps, para que puedas escribir tus propias partes que se comporten como las integradas. Es solo para React y lo hacen personas que trabajaron en Radix, Material UI y Floating UI.
UI SDK reparte las capas de otra manera. @ui-sdk/core es una biblioteca TypeScript de comportamientos: foco itinerante, typeahead, popups, drag and drop, anuncios y muchos más. Una primitiva combina comportamientos con estado y slots con nombre mediante definePrimitive. Los componentes que importas de @ui-sdk/react son primitivas renderizadas por el adaptador de React, y las mismas primitivas se renderizan en Vue, Svelte, Solid y Web Components con sus adaptadores. Su documentación lo enfoca a los agentes: dale a un agente comportamientos probados y podrá construir un componente que la biblioteca no trae, como un selector de iconos o un tablero kanban.
La diferencia práctica: en Radix y Base UI, un componente que necesitas y que no tienen es problema tuyo desde cero. En UI SDK, lo construyes con los mismos comportamientos que usan los componentes integrados, y puede unirse al puente para agentes.
El mismo popover, tres anatomías
Construí el mismo popover tres veces en una app de Vite con las mismas clases de Tailwind. Estos son los árboles, recortados a las partes que difieren:
trigger y panel son cadenas de clases compartidas, y la versión de Radix usa dos pequeñas reglas @keyframes para la entrada y la salida. El resultado se ve idéntico en las tres:

Radix
- Popover.Root
- Popover.Trigger
- Popover.Portal
- Popover.Content
Base UI
- Popover.Root
- Popover.Trigger
- Popover.Portal
- Popover.Positioner
- Popover.Popup
UI SDK
- Popover
- PopoverTrigger
- PopoverContentRenderizado en su sitio, en la top layer
Una parte que existe para mover o colocar el popup
Lo que cambia es dónde vive el contenido. En mi prueba, Radix y Base UI movieron el contenido abierto al final de <body> con su Portal. UI SDK lo dejó dentro de su propio componente, con popover="manual", y el navegador lo promovió a la top layer. Eso tiene consecuencias:
- Sin peleas de apilamiento. El contenido en la top layer queda por encima de la página sea cual sea el
z-indexde una cabecera sticky o de un padre transformado. - Los eventos burbujean por tu árbol. La documentación de UI SDK advierte de que un manejador de clic o un enlace que envuelve un popup también recibe los clics de dentro. Mantén los popups fuera de las tarjetas clicables.
- Menos partes envoltorio. Las props de posición como
side,alignysideOffsetvan en el contenido, no en un Positioner.
Radix y Base UI llevan años gestionando bien los portales, así que el primer punto es más una simplificación que un arreglo. El segundo es un comportamiento nuevo que tienes que conocer.
Hooks de estilos
Las tres ponen el estado en atributos data, pero los nombres difieren, y solo una nombra cada parte.
| Hook | Radix | Base UI | UI SDK |
|---|---|---|---|
| Estado abierto | data-state="open" | data-open | data-open |
| Nombre de parte | ninguno | ninguno | data-slot en cada parte |
| Origen de la transformación | --radix-popover-content-transform-origin | --transform-origin | --transform-origin |
| Ancho del ancla | --radix-popover-trigger-width | --anchor-width | --anchor-width |
| Estado en `className` | no | función del estado | función del estado |
La fila de data-slot importa más de lo que parece. shadcn/ui añade sus propios atributos data-slot en sus archivos wrapper, porque Radix y Base UI no emiten ninguno. En mi app de prueba, el popup de Base UI llevaba data-open, data-side y data-align, y ningún data-slot. UI SDK lo pone él mismo en cada parte, como data-slot="popover-content", y la documentación lo trata como un atributo gestionado que tus props no pueden sobrescribir. Eso da al CSS global y a los agentes un nombre estable para cada parte.
Si estilizas con Tailwind, pasar de Base UI a UI SDK es sobre todo borrar wrappers, porque los nombres de atributos del popup son compartidos. Pasar desde Radix implica sustituir las variantes data-[state=open]: y las variables con prefijo de Radix. El tutorial de estilos de UI SDK recorre cuatro componentes con tokens estilo shadcn.
Animación
Radix anima el montaje y el desmontaje con animaciones CSS sobre data-state. Su documentación dice que suspende el desmontaje mientras se reproduce la animación de salida. Para bibliotecas de animación en JavaScript, muchas partes aceptan forceMount para que la biblioteca decida cuándo se montan los hijos.
Base UI añade data-starting-style y data-ending-style, así que las transiciones CSS funcionan en ambos sentidos, no solo los keyframes. El popup sigue montado hasta que termina la animación y luego se elimina, o se oculta si el Portal tiene keepMounted. Su guía de animación cubre Motion y dice que detecta las animaciones de Motion que incluyen opacity.
UI SDK usa los mismos dos atributos con el mismo significado. El contenido sigue montado hasta que termina su transición o animación de salida, keepMounted mantiene el contenido cerrado en la página y onOpenChangeComplete se ejecuta cuando termina la apertura o el cierre. La documentación de UI SDK aún no tiene una guía para Motion, más allá de una nota para usar keepMounted cuando una biblioteca de animación necesita que el contenido cerrado siga en el DOM.
Para animación solo con CSS, Base UI y UI SDK son en la práctica iguales. Para interfaces con mucho Motion, Base UI tiene hoy patrones documentados y UI SDK no.
Cobertura de componentes
Contar componentes entre bibliotecas es aproximado, porque cada una divide y nombra las cosas de forma distinta. Como orientación:
- Radix: 30 paquetes de primitivas en
radix-ui1.8.1, de Accordion a Tooltip, más utilidades como Slot, Portal y Visually Hidden. - Base UI: 37 componentes en el índice de su documentación, incluidos Combobox, Autocomplete, Number Field, OTP Field, Drawer, Toast y Preview Card, que Radix no tiene.
- UI SDK: 55 componentes y dos hooks en la documentación incluida con 0.1.0-beta.1.
La mayoría de componentes de Base UI tienen un equivalente en UI SDK, a veces con otro nombre: Number Field es Number Input, Preview Card es Hover Card, OTP Field es OTP Input. UI SDK también trae componentes que no tiene ninguna de las otras dos, como Calendar, Date Picker, Date Input, Time Input, Color Picker, Rating, Tree, Command, Carousel, Resizable, Image Cropper, File Input, Token Input, Trigger Menu, Timeline y Waterfall.
Cantidad no es calidad. Los componentes de Radix y Base UI tienen años de uso en producción detrás. Las páginas de componentes de UI SDK listan sus comportamientos probados línea a línea, lo que es buena señal, pero un día de vida pública no es lo mismo que años de reportes de bugs.
El puente para agentes
Esta es la parte que solo tiene UI SDK. createAgent() de @ui-sdk/react/agent se conecta a cada componente de UI SDK de la página. snapshot() los lista con sus labels, su estado y las acciones disponibles. act() llama a esas acciones a través de la API de cada componente, y tus callbacks de cambio ven details.source === "agent". registerTools() ofrece las mismas herramientas a un agente integrado en el navegador mediante WebMCP.
Radix y Base UI no tienen nada parecido integrado. Un agente las maneja como maneja cualquier página web: con capturas de pantalla, el DOM o el árbol de accesibilidad, mediante herramientas de navegador que hacen clic y escriben.
La documentación de Vercel incluye un benchmark de esa diferencia en una tarea de ajustes de proyecto. Según sus números, con Sonnet en Claude Code y medianas de tres ejecuciones, el puente para agentes redujo las llamadas a herramientas de 16 a 5 y el coste de $0.073 a $0.032. Son cifras de Vercel para una tarea, no mías, pero la dirección tiene sentido: leer una lista de componentes con su estado es más barato que leer una página. Hice una demo funcional del puente, con permisos y un componente personalizado, en Haz que agentes de IA puedan operar tu app React.
Si que agentes usen tu UI no está en tu hoja de ruta, esta sección no debería decidir nada. Si lo está, nada más en esta comparación se le acerca.
Madurez y licencia
Radix y Base UI son bibliotecas 1.x estables. Sus APIs cambian siguiendo semver, y shadcn/ui publica todos los componentes para ambas.
UI SDK dice en su README y en su documentación que está en beta y que el framework, las APIs, la documentación y el comportamiento pueden cambiar antes de la disponibilidad general. Su beta está cubierta por el acuerdo de beta pública de Vercel. Además, algunas APIs están marcadas como experimentales, como la clave agent en primitivas personalizadas y los helpers de historial y deshacer. El repositorio de GitHub, vercel-labs/ui, se creó en octubre de 2026, y la única entrada del changelog es "Introducing UI SDK", del 12 de noviembre de 2026.
Las licencias también difieren. Radix y Base UI son MIT. UI SDK es Apache-2.0, que también es permisiva y añade una concesión explícita de patentes. Si lo redistribuyes, Apache-2.0 te pide conservar su licencia y sus avisos, así que consúltalo con quien lleve las licencias en tu empresa si te afecta.
Frameworks
Radix y Base UI son bibliotecas de React. UI SDK publica @ui-sdk/react, @ui-sdk/vue, @ui-sdk/svelte, @ui-sdk/solid y @ui-sdk/web con la misma versión, todas sobre un mismo core. Si tu empresa tiene una app React y una app Vue, o quiere un build de Web Components para un CMS, UI SDK es la única de las tres que las cubre todas con un solo conjunto de comportamientos y nombres de atributos.
El paquete de React de UI SDK requiere React 19 y React DOM 19 o posterior, con @types/react 19.2.10 o posterior. Si sigues en React 18, eso lo decide por ahora.
Cuándo elegir cada una
Quédate en Radix si la app funciona, el equipo lo conoce y nada te bloquea. Nada de esto obliga a cambiar. Si cambias, pasa primero a Base UI: es el paso más pequeño, y el modelo de atributos que aprendas te sirve para UI SDK.
Empieza con Base UI si estás construyendo una biblioteca de componentes React o una UI de producto para publicar ya. Es estable, es la opción por defecto de shadcn/ui y sus patrones de popups, formularios y animación están bien documentados.
Empieza con UI SDK si se cumple alguna de estas condiciones:
- necesitas que varios frameworks compartan un mismo modelo de componentes;
- necesitas sus componentes extra y, si no, añadirías bibliotecas para fechas, colores o árboles;
- que agentes operen tu UI es un objetivo de producto, y quieres permisos y orígenes de cambio integrados;
- estás prototipando y puedes asumir cambios incompatibles durante la beta.
Se pueden mezclar. Los componentes de UI SDK no necesitan provider, así que una app con Base UI puede usar un Color Picker de UI SDK en una pantalla. Cargas con dos dependencias y dos juegos de nombres de atributos, así que limítalo a los componentes que no puedes conseguir en otro sitio.
Qué está haciendo HextaUI
Los componentes de HextaUI siguen en Base UI. Esa variante es la que hay hoy en el sitio y no va a desaparecer. También estoy construyendo una variante separada sobre UI SDK con el mismo aspecto y los mismos tokens de tema, para proyectos que quieran el puente para agentes o los componentes extra. Aún no está publicada. Cuando lo esté, elegirás una variante, no migrarás.
