Introduction
Radix UI Primitives is a collection of low-level, unstyled React components designed to be the foundation of custom design systems. Each primitive handles complex UI behaviors like focus management, keyboard navigation, and screen reader announcements, while leaving all visual styling to you. It is the component layer that powers shadcn/ui and many other design systems.
What Radix UI Does
- Provides 30+ unstyled, accessible React primitives including Dialog, Dropdown Menu, Popover, Tabs, and Toast
- Handles WAI-ARIA patterns, keyboard interactions, and focus trapping for each component
- Ships each primitive as a separate npm package so you install only what you need
- Uses a composable API with named sub-components (Root, Trigger, Content, etc.) for flexible composition
- Supports controlled and uncontrolled usage patterns with consistent prop conventions
Architecture Overview
Radix UI uses a compound component pattern where each primitive is split into named parts. For example, Dialog.Root manages open/close state, Dialog.Trigger opens the dialog, Dialog.Content renders the panel, and Dialog.Close dismisses it. Internally, primitives use React context to share state between parts, React portals for overlays, and the Floating UI library for positioning. All ARIA attributes, keyboard handlers, and focus management are built into the primitive layer.
Self-Hosting & Configuration
- Install individual primitives:
npm install @radix-ui/react-[component](e.g.,react-dialog,react-popover) - Import named exports and compose sub-components in your JSX
- Apply styles using any CSS approach: Tailwind, CSS Modules, styled-components, or plain CSS
- Use the
asChildprop to merge primitive behavior onto your own custom elements - Wrap the app in
Themefrom@radix-ui/themesif you want Radix's optional pre-styled theme layer
Key Features
- Fully accessible with WAI-ARIA compliance, keyboard navigation, and screen reader support out of the box
- Completely unstyled primitives give total control over visual design
- Tree-shakable with each component in its own package (no monolithic bundle)
asChildcomposition pattern lets you use primitives on any element or component- Powers shadcn/ui, making it the de facto foundation for Tailwind-based React design systems
Comparison with Similar Tools
- Headless UI — similar unstyled approach for React and Vue; Radix offers more primitives and granular sub-components
- shadcn/ui — pre-styled copy-paste components built on Radix; Radix is the underlying behavior layer
- React Aria (Adobe) — hooks-based accessibility primitives; Radix provides ready-made component structures
- Ark UI — framework-agnostic headless components; Radix is React-specific with deeper ecosystem integration
- Mantine — fully styled component library; Radix separates behavior from styling for maximum customization
FAQ
Q: How is Radix UI different from shadcn/ui? A: shadcn/ui is built on top of Radix UI. Radix provides the unstyled, accessible behavior layer, while shadcn/ui adds Tailwind CSS styling on top.
Q: Do I need to install the entire library? A: No. Each primitive is a separate npm package. Install only the components you use.
Q: Can I use Radix UI with CSS frameworks other than Tailwind? A: Yes. Radix primitives are completely unstyled, so they work with any CSS solution: plain CSS, CSS Modules, Sass, styled-components, or Emotion.
Q: Does Radix UI support server-side rendering? A: Yes. Radix primitives support SSR and work with Next.js, Remix, and other React SSR frameworks.