Radix UI

Radix UI

Unstyled accessible primitives

Features

  • WAI-ARIA compliant accessible components
  • Completely unstyled — bring your own design
  • Composable API with granular sub-components
  • Keyboard navigation and focus management
  • Collision-aware positioning for popovers/tooltips

Pros

  • Best-in-class accessibility out of the box
  • No style opinions — full design freedom
  • Composable API for maximum flexibility
  • Foundation for shadcn/ui and many design systems

Cons

  • React-only
  • Requires significant styling effort for production use
  • API surface can be verbose for simple use cases

Overview

Radix UI is a library of unstyled, accessible UI primitives for React. Each component handles the complex accessibility requirements (ARIA attributes, keyboard navigation, focus management, screen reader support) while giving you complete control over styling and rendering.

Radix primitives use a composable sub-component API — a Dialog is composed of Dialog.Root, Dialog.Trigger, Dialog.Content, and so on. This granular API gives you full control over markup structure while the library handles the behavior and accessibility. Radix is the foundation that powers shadcn/ui and many custom design systems.

When to Use

Radix UI is the right choice when you need accessible component primitives with zero styling opinions, when building a custom design system from scratch, or when you need fine-grained control over component markup and behavior. It’s the foundation layer when shadcn/ui’s defaults aren’t what you need.

Getting Started

npm install @radix-ui/react-dialog
import * as Dialog from "@radix-ui/react-dialog";

function MyDialog() {
  return (
    <Dialog.Root>
      <Dialog.Trigger>Open</Dialog.Trigger>
      <Dialog.Portal>
        <Dialog.Overlay className="fixed inset-0 bg-black/50" />
        <Dialog.Content className="fixed inset-center rounded bg-white p-6">
          <Dialog.Title>Edit Profile</Dialog.Title>
          <Dialog.Close>Close</Dialog.Close>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}