What is Base UI?
Base UI: Base UI is an open source library of unstyled, accessible React components from the team behind Radix, Floating UI and Material UI.
Base UI (@base-ui/react) provides the behavior of interactive components such as dialogs, menus, popovers, selects, tabs, sliders and accordions, with no visual styles. Each component handles focus management, keyboard interaction, ARIA roles and states, and positioning, and leaves every pixel to you. It comes from people who built Radix Primitives, Floating UI and Material UI, and it applies lessons from all three. It is a headless component library in the same category as Radix UI and React Aria.
How it works
Components are compound: a root that owns state, and parts you compose. Each part renders one DOM element that you style with className. State is exposed as data attributes such as data-open, data-disabled and data-highlighted, so Tailwind variants like data-open:opacity-100 style it without extra props. Where Radix uses asChild to change the rendered element, Base UI uses a render prop.
className and style also accept a function of the component's state, which helps when a class depends on more than one flag. Popups are split into Portal, Positioner and Popup parts, so placement logic stays separate from the element you style. A basic popover looks like this:
import { Popover } from "@base-ui/react/popover"
export function InfoPopover() {
return (
<Popover.Root>
<Popover.Trigger className="rounded-lg border px-3 py-1.5">Info</Popover.Trigger>
<Popover.Portal>
<Popover.Positioner sideOffset={8}>
<Popover.Popup className="rounded-xl border bg-raised p-4 shadow-overlay">
Details go here.
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
)
}
Why it matters
- Accessibility you do not re-derive. Focus trapping, focus return, typeahead, roving tab index and the right ARIA wiring come from tested code instead of your sprint.
- Styling freedom. There is nothing to override. Tailwind classes and your design tokens are the only visual layer.
- Animation hooks.
data-starting-styleanddata-ending-styleattributes let plain CSS transitions handle enter and exit, without a separate animation library. - Positioning built in. Popups use Floating UI techniques for collision handling, so menus flip and shift at viewport edges.
- Components Radix lacks. Base UI includes pieces such as a combobox and a number field.
The trade-off is the same as with any headless library: you write the styles, and you own details such as visible focus rings, contrast and reduced motion. If you want those finished, use a styled layer built on top of it.
How MiniDev UI uses it
MiniDev UI builds its interactive primitives on Base UI: Dialog, Popover, Select, Tabs, Accordion, Tooltip and Dropdown menu all depend on @base-ui/react, and add the kit's tokens, shadows and motion on top. shadcn/ui supports Base UI as an alternative to Radix, so these components sit comfortably in a shadcn project. Installing one pulls in the dependency automatically:
npx shadcn@latest add https://ui.minidev.pro/r/popover.json