📁 radixui/primitives

File: primitives.md | Updated: 11/15/2025

Source: https://www.radix-ui.com/primitives

Radix Homepage

Made by WorkOS

Radix Homepage

Made by WorkOS

ThemesThemes PrimitivesPrimitives IconsIcons ColorsColors

Documentation Case studies Blog

Core building blocks for your design system

Unstyled, accessible, open source React primitives for high-quality web apps and design systems.

Get started

Edit Profile

Edit Profile

Name

Username

Save

Dialog

With modal and non-modal modes, fine-grained focus control, accessible to screen readers.

Options

New Tab

New Window

Favorites

Downloads

Show Toolbar

Show Full URLs

Dropdown Menu

With submenus, checkable items, collision handling, arrow key navigation, and typeahead support.

Dimensions

Dimensions

Width

Height

Margin

Padding

Popover

With fine-grained focus control, collision handling, origin-aware and collision-aware animations.

Slider

Supports keyboard and touch input, step interval, multiple thumbs for value ranges, and RTL direction.

Tags

v1.2.0-beta.50

v1.2.0-beta.49

v1.2.0-beta.48

v1.2.0-beta.47

v1.2.0-beta.46

v1.2.0-beta.45

v1.2.0-beta.44

v1.2.0-beta.43

v1.2.0-beta.42

v1.2.0-beta.41

v1.2.0-beta.40

v1.2.0-beta.39

v1.2.0-beta.38

v1.2.0-beta.37

v1.2.0-beta.36

v1.2.0-beta.35

v1.2.0-beta.34

v1.2.0-beta.33

v1.2.0-beta.32

v1.2.0-beta.31

v1.2.0-beta.30

v1.2.0-beta.29

v1.2.0-beta.28

v1.2.0-beta.27

v1.2.0-beta.26

v1.2.0-beta.25

v1.2.0-beta.24

v1.2.0-beta.23

v1.2.0-beta.22

v1.2.0-beta.21

v1.2.0-beta.20

v1.2.0-beta.19

v1.2.0-beta.18

v1.2.0-beta.17

v1.2.0-beta.16

v1.2.0-beta.15

v1.2.0-beta.14

v1.2.0-beta.13

v1.2.0-beta.12

v1.2.0-beta.11

v1.2.0-beta.10

v1.2.0-beta.9

v1.2.0-beta.8

v1.2.0-beta.7

v1.2.0-beta.6

v1.2.0-beta.5

v1.2.0-beta.4

v1.2.0-beta.3

v1.2.0-beta.2

v1.2.0-beta.1

Scroll Area

Supports custom cross-browser styling while maintaining the browser's native scroll behavior.

AccountPassword

Name

Username

Save

Tabs

Supports arrow key navigation, horizontal/vertical orientation, controlled or uncontrolled.

Is it accessible?

Yes. The Accordion adheres to the WAI‑ARIA design pattern.

Is it unstyled?

Can it be animated?

Accordion

Supports one or multiple items open at the same time, keyboard navigation, collapse and expand animation.

Indigo Blue

Taupe Brown

Slate Gray

Radio Group

With arrow key navigation, horizontal/vertical orientation support, controlled or uncontrolled.

Toggle Group

A set of two-state buttons that can be toggled on or off. Supports single and multiple pressed buttons.

Switch

Allows the user to toggle between checked and not checked.

See more components in the docsView docs

Case studies

World-class teams use Radix Primitives to power their products

Node.js case study

“Radix Primitives are crucial for the Node.js website and are a significant part of Node’s Web Design System. It allows our engineers to focus on what matters and create delightful experiences for the community.”

Claudio Wunder, Node.js Core Collaborator
Vercel case study

“We’ve been able to focus on building solid user experiences on top of Radix Primitives. With UI components, there are just too many angles and rabbit holes to cover for product teams that wish to move quickly.”

Rauno Freiberg, UI Engineer at Vercel

And dozens more companies

Basedash case study basement.studio case study CodeSandbox case study Linear case study Liveblocks case study Supabase case study University of Amsterdam case study

Why Radix Primitives

Spend less time on
undifferentiated work

Save time. Ship faster.

It takes a lot of time to develop and maintain a robust set of UI components, and it's mostly undifferentiated work. Building on top of Radix components will save you time and money, so you can ship a better product faster.

Focus on your product

It’s no secret that robust UI components are tricky to build. Nailing accessibility details and complex logic sucks time away from product feature development. With Radix, you can focus on your unique engineering challenges instead.

130M+

Monthly downloads

5500+

Discord members

13K+

GitHub stars

Case in point

So, you think you can build a dropdown?

We agonise over API design, performance, and accessibility so you don't need to.

A dropdown menu example with a checked item and a submenu

Full keyboard navigation

Navigate the menu using arrow keys, Escape, and Enter hotkeys, or even via typeahead.

Modal and non-modal modes

Configure whether the dropdown menu allows or blocks outside interactions.

Supports submenus

Nest another level of fully functional submenus inside the dropdown menu.

Supports assistive technology

Implements correct semantics and behaviors, so it's accessible to people using assistive technology.

Collision and origin-aware animations

Create open and close animations that take the dropdown menu’s actual position into account.

Control alignment and collisions

Position the menu anywhere relative to the trigger, taking collisions with the screen into account.

Fully managed focus

Granularly control focus behavior when user closes the dropdown menu or focuses an outside element.

Supports checkable items

Items can be used to perform actions, as well as act as checkbox or radiobutton controls.

Supports assistive technology

Accessibility out of the box

Screen reader supportTypeahead supportKeyboard navigationRTL support

Screen reader

Show Minimap,
ticked, menu item

Radix component

Navigation

Show Minimap

Go to Symbol

Go to Definition

Go to References

WAI-ARIA compliant

Radix Primitives follow the WAI-ARIA guidelines, implementing correct semantics and behaviors for our components.

Keyboard navigation

Primitives provide full keyboard support for components where users expect to use a keyboard or other input devices.

Focus management

Out of the box, Primitives provide sensible focus management defaults, which can be further customized in your code.

Screen reader tested

We test Primitives with common assistive technologies, looking out for practical issues that people may experience.

Developer experience to love

Develop with an open, thought‑out API

One of our main goals is to provide the best possible developer experience. Radix Primitives provides a fully-typed API. All components share a similar API, creating a consistent and predictable experience.

// Add styles with your preferred CSS technology
const TooltipContent = styled(Tooltip.Content, {
	backgroundColor: "black",
	borderRadius: "3px",
	padding: "5px"
});

const PopoverContent = styled(Popover.Content, {
	backgroundColor: "white",
	boxShadow: "0 2px 10px -3px rgb(0 0 0 / 20%)",
	borderRadius: "3px",
});

const DialogContent = styled(Dialog.Content, {
	backgroundColor: "white",
	boxShadow: "0 3px 15px -4px rgb(0 0 0 / 30%)",
	borderRadius: "5px",
});

Unstyled

No need to override styles, no specificity wars.

// Compose a custom Tooltip component
export const StatusTooltip = ({ state, label }) => {
	return (
		<Tooltip.Root>
			<Tooltip.Trigger asChild>
				<Text>
					<Status variant={state} />
				</Text>
			</Tooltip.Trigger>
			<Tooltip.Portal>
				<TooltipContent>
					<Tooltip.Arrow />
					{label}
				</TooltipContent>
			</Tooltip.Portal>
		</Tooltip.Root>
	);
};

Composable

Granular access to each component part.

// Compose a Popover with custom focus and positioning
export const StatusPopover = ({ children }) => {
	const popoverCloseButton = React.useRef(null);
	return (
		<Popover.Root>
			<Popover.Trigger>View status</Popover.Trigger>
			<Popover.Portal>
				<PopoverContent
					align="start"
					collisionPadding={10}
					onOpenAutoFocus={(event) => {
						// Focus the close button when popover opens
						popoverCloseButton.current?.focus();
						event.preventDefault();
					}}
				>
					{children}
					<Popover.Close ref={popoverCloseButton}>
						Close
					</Popover.Close>
				</PopoverContent>
			</Popover.Portal>
		</Popover.Root>
	);
};

Customizable

Configure behavior, control focus, add event listeners.

// Compose a Dialog with custom focus management
export const InfoDialog = ({ children }) => {
	const dialogCloseButton = React.useRef(null);
	return (
		<Dialog.Root>
			<Dialog.Trigger>View details</Dialog.Trigger>
			<Dialog.Overlay />
			<Dialog.Portal>
				<DialogContent
					onOpenAutoFocus={(event) => {
						// Focus the close button when dialog opens
						dialogCloseButton.current?.focus();
						event.preventDefault();
					}}
				>
					{children}
					<Dialog.Close ref={dialogCloseButton}>
						Close
					</Dialog.Close>
				</DialogContent>
			</Dialog.Portal>
		</Dialog.Root>
	);
};

Consistent

Components with similar functionality share similar API.

Unstyled

No need to override styles, no specificity wars.

Composable

Granular access to each component part.

Customizable

Configure behavior, control focus, add event listeners.

Consistent

Components with similar functionality share similar API.

MyComponent.jsx

// Add styles with your preferred CSS technology
const TooltipContent = styled(Tooltip.Content, {
	backgroundColor: "black",
	borderRadius: "3px",
	padding: "5px"
});

const PopoverContent = styled(Popover.Content, {
	backgroundColor: "white",
	boxShadow: "0 2px 10px -3px rgb(0 0 0 / 20%)",
	borderRadius: "3px",
});

const DialogContent = styled(Dialog.Content, {
	backgroundColor: "white",
	boxShadow: "0 3px 15px -4px rgb(0 0 0 / 30%)",
	borderRadius: "5px",
});	

// Compose a custom Tooltip component
export const StatusTooltip = ({ state, label }) => {
	return (
		<Tooltip.Root>
			<Tooltip.Trigger asChild>
				<Text>
					<Status variant={state} />
				</Text>
			</Tooltip.Trigger>
			<Tooltip.Portal>
				<TooltipContent>
					<Tooltip.Arrow />
					{label}
				</TooltipContent>
			</Tooltip.Portal>
		</Tooltip.Root>
	);
};	// Compose a Popover with custom focus and positioning
export const StatusPopover = ({ children }) => {
	const popoverCloseButton = React.useRef(null);
	return (
		<Popover.Root>
			<Popover.Trigger>View status</Popover.Trigger>
			<Popover.Portal>
				<PopoverContent
					align="start"
					collisionPadding={10}
					onOpenAutoFocus={(event) => {
						// Focus the close button when popover opens
						popoverCloseButton.current?.focus();
						event.preventDefault();
					}}
				>
					{children}
					<Popover.Close ref={popoverCloseButton}>
						Close
					</Popover.Close>
				</PopoverContent>
			</Popover.Portal>
		</Popover.Root>
	);
};	// Compose a Dialog with custom focus management
export const InfoDialog = ({ children }) => {
	const dialogCloseButton = React.useRef(null);
	return (
		<Dialog.Root>
			<Dialog.Trigger>View details</Dialog.Trigger>
			<Dialog.Overlay />
			<Dialog.Portal>
				<DialogContent
					onOpenAutoFocus={(event) => {
						// Focus the close button when dialog opens
						dialogCloseButton.current?.focus();
						event.preventDefault();
					}}
				>
					{children}
					<Dialog.Close ref={dialogCloseButton}>
						Close
					</Dialog.Close>
				</DialogContent>
			</Dialog.Portal>
		</Dialog.Root>
	);
};

Transition to Radix Primitives

Adoption made easy

Go to docs

Incremental adoption

Each component is its own independently versioned package, so new components can be added alongside your existing code. No need to disrupt feature work with a huge rewrite⁠—you can start small and add more components one by one.

Detailed docs and TypeScript support

Radix documentation contains real-world examples, extensive API references, accessibility details, and full TypeScript support. All components share a similar API, creating a consistent developer experience. You will love working with Radix Primitives.

An active and friendly community

👋

Join our fast-growing community

### Bluesky

For announcements, updates, and general Radix tips.
### Discord

To get involved in the community, ask questions, and share tips.
### GitHub

To file issues, request features, and contribute, check out our GitHub.

📁 Children

Directory listing - 3 item(s) total