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.

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>
);
};

Top performing

Supercharged by Bun runtime, Static Code Analysis, and Dynamic Code Injection, The top-performing TypeScript frameworks.

Focus on productivity

From built-in strict-type validation to a unified type system, and documentation generation, making an ideal framework.

WinterCG compliant

Being WinterCG compliant, it can run in your browser! Edit the code and see live update immediately.