React is a powerful UI library, but it doesn’t come with built-in components like buttons, modals, or dropdowns. To build polished, accessible, and consistent interfaces, developers often rely on component libraries. Two modern libraries that stand out in this space are Shadcn UI and Radix UI.
This module introduces both libraries, explains their relationship, and shows how they work together to help developers build fast, accessible, and customizable interfaces without reinventing the wheel.
Overview
- Radix UI is a low-level component library focused on accessibility and behavior.
- Shadcn UI is a styled, higher-level UI system that wraps Radix primitives using Tailwind CSS, offering beautiful, ready-to-use components.
1. What is Radix UI?
Radix UI provides unstyled, accessible primitives for building components. These are headless (logic only) building blocks, giving developers full control over how components look while offering a robust, accessible structure.
Why Use Radix UI?
- Accessibility First: Components follow WAI-ARIA standards by default.
- Headless Approach: Full control over styling and composition.
- Composability: Components like
Dialog
,Popover
, andTabs
are built to work with React composition patterns. - No Style Imposition: You’re free to use Tailwind, CSS-in-JS, or plain CSS.
Popular Primitives in Radix UI
@radix-ui/react-dialog
: Accessible modal dialogs.@radix-ui/react-popover
: Tooltips and popovers.@radix-ui/react-tabs
: Keyboard-navigable tab interfaces.@radix-ui/react-switch
: Toggle switches with ARIA support.@radix-ui/react-toast
: Notifications and alerts.
Installation Example:
bashCopyEditnpm install @radix-ui/react-dialog
Usage Example:
jsxCopyEditimport * as Dialog from '@radix-ui/react-dialog';
const Modal = () => (
<Dialog.Root>
<Dialog.Trigger>Open Modal</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black/50" />
<Dialog.Content className="bg-white p-4 rounded-lg shadow">
<Dialog.Title>Edit Profile</Dialog.Title>
<Dialog.Description>Make changes to your profile here.</Dialog.Description>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
You can style the components however you want using Tailwind or any other system.
2. What is Shadcn UI?
Shadcn UI is a library that provides pre-styled, Tailwind-powered, Radix-based components. Think of it as a production-ready UI kit that combines the accessibility of Radix with the utility-first design of Tailwind CSS.
Why Shadcn UI?
- Built on Radix UI: All components inherit Radix’s accessibility and behavior.
- Uses Tailwind CSS: Seamless utility-based styling.
- Fully Customizable: Components are generated into your codebase — you own and modify them.
- Beautifully Designed: Comes with thoughtful spacing, typography, and animations.
- Non-opaque: No vendor lock-in, no hidden styles or behaviors.
Installing Shadcn UI
To set up Shadcn UI in a React + Tailwind project:
bashCopyEditnpx shadcn-ui@latest init
It will ask questions like:
- Framework (e.g., Next.js)
- CSS framework (e.g., Tailwind)
- UI preferences (e.g., radix support, component directory)
After setup, you can add components like:
bashCopyEditnpx shadcn-ui@latest add button
npx shadcn-ui@latest add dialog
Example Button Component (Shadcn UI)
jsxCopyEditimport { Button } from "@/components/ui/button";
export default function App() {
return (
<Button variant="outline" size="lg">
Click Me
</Button>
);
}
Behind the scenes, this is a Tailwind-styled component using Radix primitives, generated into your codebase at components/ui/button.tsx
.
3. Shadcn UI vs Radix UI: When to Use What?
Feature | Radix UI | Shadcn UI |
---|---|---|
Styling | Unstyled | Tailwind CSS (pre-styled) |
Customization | 100% customizable from scratch | 100% customizable by editing generated code |
Accessibility | High (WAI-ARIA compliant) | Inherits Radix’s accessibility features |
Learning Curve | Higher (low-level primitives) | Lower (plug and play) |
Ideal for | Design systems, component authors | App builders, fast prototyping |
4. When to Use Them Together
You don’t need to choose one or the other — Shadcn UI uses Radix UI under the hood. Use Shadcn when you want speed and polish, and drop down to Radix if you need more control or want to build a highly custom interaction.
Example:
- Use
shadcn/ui
for most common components (Button
,Dialog
,Tabs
,Tooltip
). - Use
@radix-ui/react-*
directly for custom behavior with your own design system.
5. Recommended Practices
- Install Only What You Need: Shadcn allows you to add components individually.
- Customize Early: Don’t treat Shadcn as a black box — modify and tailor components as per your design needs.
- Extend Components: You can wrap base components to create variants, themes, or logic extensions.
- Stay Updated: Both libraries evolve rapidly — keep an eye on changelogs and updates.
Conclusion
Radix UI and Shadcn UI bring together accessibility, modularity, and developer ergonomics. They give you a modern workflow to build UI components in React that are both beautiful and accessible out of the box. Whether you’re building a quick MVP or a production-grade system, this combination gives you the flexibility and control to do it right.