MUI is bloated. Chakra forces its styling system. Ant Design looks like every other enterprise app. shadcn/ui takes a different approach — instead of installing a package, you COPY components into your project. You own the code. You customize everything.
What shadcn/ui Gives You for Free
- 50+ components — Button, Dialog, Table, Form, Chart, and more
- Copy-paste, not install — components live in YOUR codebase
- Radix UI primitives — accessible, unstyled foundations
- Tailwind CSS — style with utility classes you already know
-
CLI tool —
npx shadcn@latest add buttoncopies the component - Themes — customize colors, radius, fonts via CSS variables
- TypeScript — fully typed, customizable
Quick Start
npx shadcn@latest init
This sets up your project with Tailwind CSS, CSS variables, and a components/ui directory.
Adding Components
# Add individual components
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add table
npx shadcn@latest add form
# The code goes into YOUR project:
# src/components/ui/button.tsx
# src/components/ui/dialog.tsx
# etc.
Using Components
import { Button } from '@/components/ui/button';
import {
Dialog, DialogContent, DialogHeader,
DialogTitle, DialogTrigger
} from '@/components/ui/dialog';
export function CreateUser() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Create User</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>New User</DialogTitle>
</DialogHeader>
<form className="space-y-4">
<Input placeholder="Name" />
<Input placeholder="Email" type="email" />
<Button type="submit" className="w-full">Create</Button>
</form>
</DialogContent>
</Dialog>
);
}
Customization (You Own the Code)
// src/components/ui/button.tsx — this is YOUR file, modify freely
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border border-input bg-background hover:bg-accent',
// Add YOUR custom variants:
gradient: 'bg-gradient-to-r from-blue-500 to-purple-600 text-white',
glass: 'bg-white/10 backdrop-blur-md border border-white/20',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
}
);
Theming (CSS Variables)
/* globals.css */
:root {
--primary: 222.2 84% 4.9%;
--primary-foreground: 210 40% 98%;
--radius: 0.5rem;
}
.dark {
--primary: 210 40% 98%;
--primary-foreground: 222.2 84% 4.9%;
}
Change ONE variable, every component updates. Dark mode is built in.
Data Table (Powered by TanStack Table)
import { DataTable } from '@/components/ui/data-table';
import { columns } from './columns';
export default function UsersPage() {
const users = await getUsers();
return <DataTable columns={columns} data={users} />;
}
Sorting, filtering, pagination — all included.
shadcn/ui vs Other Libraries
| Feature | shadcn/ui | MUI | Chakra | Ant Design |
|---|---|---|---|---|
| Ownership | Your code | npm package | npm package | npm package |
| Bundle impact | Only what you use | 300KB+ | 200KB+ | 400KB+ |
| Styling | Tailwind | Emotion/styled | Chakra system | Less/CSS |
| Customization | Full (own source) | Theme overrides | Theme overrides | Less variables |
| Updates | Your choice | npm update | npm update | npm update |
| Lock-in | Zero | High | Medium | High |
Who's Using shadcn/ui
- Vercel — v0.dev uses shadcn/ui as its component system
- Cal.com, Dub.co, Papermark — open-source companies
- Most-starred React UI project on GitHub in 2024-2025
The Verdict
shadcn/ui flips the UI library model: instead of depending on a package you can't modify, you own every line of component code. Accessible foundations (Radix), beautiful defaults (Tailwind), zero lock-in. The future of React UI.
Need help building production web scrapers or data pipelines? I build custom solutions. Reach out: spinov001@gmail.com
Check out my awesome-web-scraping collection — 400+ tools for extracting web data.
Top comments (0)