Radix UI
Unstyled, accessible primitives for React.
Radix UI ships behaviour without appearance: focus traps, roving tabindex, keyboard navigation, ARIA semantics and controlled or uncontrolled state. It became the default primitive layer for React because shadcn/ui built on it, and it still runs under a very large number of production apps.
At a glance
| Install | per component, e.g. @radix-ui/react-dialog |
| Styling | none, fully agnostic |
| Composition | asChild merges behaviour onto your own element |
| Server components | client-side, needs a client boundary |
| MCP server | not published |
| Maintenance | acquired by WorkOS, cadence slowed |
| License | MIT |
Install
One package per primitive, so you only pay for what you use.
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu
What the code looks like
asChild is the pattern worth learning: it hands the behaviour to your element instead of wrapping it, so your markup and class names survive.
import * as Dialog from "@radix-ui/react-dialog"
<Dialog.Root>
<Dialog.Trigger asChild>
<button className="btn btn-danger">Delete</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="overlay" />
<Dialog.Content className="panel">
<Dialog.Title>Are you sure?</Dialog.Title>
<Dialog.Close asChild>
<button className="btn">Cancel</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
The maintenance question
Nothing is deprecated and nothing is broken. But the project was acquired by WorkOS, releases have slowed on the more complex components, and new investment in this space is going into Base UI.
Choose it if
- You have an existing codebase on it. There is no reason to migrate.
- You want the largest body of community examples and Stack Overflow answers.
Look elsewhere if
- You are starting a new project and want the layer under active development.
- You want a styled result out of the box, in which case Radix Themes sits directly on top of these primitives.