Shadcn/UI Components

Beautiful, accessible components built with Radix UI and Tailwind

🎨 What is Shadcn/UI?

Shadcn/UI is a collection of reusable components built with Radix UI and Tailwind CSS. Unlike traditional component libraries, you copy components directly into your project, giving you full control and customization.


# Initialize Shadcn/UI in your Next.js project
npx shadcn@latest init

# Add components as needed
npx shadcn@latest add button
npx shadcn@latest add card
                                    

Key Shadcn/UI Features

📦

Copy & Paste

Components live in your codebase

npx shadcn@latest add button
♿

Accessible

Built on Radix UI primitives

<Button>
  Accessible by default
</Button>
🎨

Customizable

Full control over styling

<Button variant="outline">
  Custom Style
</Button>
🌙

Dark Mode

Built-in theme support

<ThemeProvider>
  {children}
</ThemeProvider>

🔹 Setting Up Shadcn/UI

Initialize Shadcn/UI in your Next.js project with a simple command. The CLI will configure Tailwind CSS, create necessary files, and set up your component structure automatically.

# Create a new Next.js project
npx create-next-app@latest my-app

# Navigate to your project
cd my-app

# Initialize Shadcn/UI
npx shadcn@latest init

# Follow the prompts to configure:
# - TypeScript: Yes
# - Style: Default
# - Base color: Slate
# - CSS variables: Yes

Created Files:

components/ui/
lib/utils.ts
tailwind.config.js (updated)
app/globals.css (updated)

🔹 Button Component

Add and use the Button component with multiple variants. Shadcn/UI buttons come with built-in variants like default, destructive, outline, and ghost for different use cases.

# Add the button component
npx shadcn@latest add button
// app/page.js
import { Button } from "@/components/ui/button"

export default function Home() {
  return (
    <div className="p-8 space-y-4">
      <Button>Default Button</Button>
      <Button variant="destructive">Delete</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="link">Link</Button>
      
      <Button size="sm">Small</Button>
      <Button size="lg">Large</Button>
      <Button size="icon">🚀</Button>
    </div>
  )
}

🔹 Card Component

Create beautiful card layouts with the Card component. Cards include sub-components like CardHeader, CardTitle, CardDescription, CardContent, and CardFooter for structured content.

# Add the card component
npx shadcn@latest add card
// components/ProductCard.js
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Button } from "@/components/ui/button"

export default function ProductCard() {
  return (
    <Card className="w-[350px]">
      <CardHeader>
        <CardTitle>Premium Plan</CardTitle>
        <CardDescription>
          Perfect for growing teams
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p className="text-3xl font-bold">$29/month</p>
        <ul className="mt-4 space-y-2">
          <li>✓ Unlimited projects</li>
          <li>✓ Priority support</li>
          <li>✓ Advanced analytics</li>
        </ul>
      </CardContent>
      <CardFooter>
        <Button className="w-full">Subscribe</Button>
      </CardFooter>
    </Card>
  )
}

🔹 Form Components

Build accessible forms with Input, Label, and Form components. Shadcn/UI forms integrate with React Hook Form for validation and state management.

# Add form components
npx shadcn@latest add input
npx shadcn@latest add label
npx shadcn@latest add form
// components/LoginForm.js
'use client'
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export default function LoginForm() {
  return (
    <form className="space-y-4 w-full max-w-sm">
      <div className="space-y-2">
        <Label htmlFor="email">Email</Label>
        <Input 
          id="email" 
          type="email" 
          placeholder="[email protected]"
        />
      </div>
      
      <div className="space-y-2">
        <Label htmlFor="password">Password</Label>
        <Input 
          id="password" 
          type="password"
          placeholder="••••••••"
        />
      </div>
      
      <Button type="submit" className="w-full">
        Sign In
      </Button>
    </form>
  )
}

🔹 Dialog Component

Create modal dialogs for confirmations, forms, and alerts. The Dialog component is fully accessible with keyboard navigation and focus management built-in.

# Add dialog component
npx shadcn@latest add dialog
// components/DeleteDialog.js
'use client'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"

export default function DeleteDialog() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="destructive">Delete Account</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Are you sure?</DialogTitle>
          <DialogDescription>
            This action cannot be undone. This will permanently
            delete your account and remove your data.
          </DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <Button variant="outline">Cancel</Button>
          <Button variant="destructive">Delete</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

🔹 Dropdown Menu

Create dropdown menus for navigation and actions. Dropdown menus support nested items, separators, checkboxes, and radio groups for complex menu structures.

# Add dropdown menu
npx shadcn@latest add dropdown-menu
// components/UserMenu.js
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Button } from "@/components/ui/button"

export default function UserMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline">My Account</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuLabel>My Account</DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuItem>Profile</DropdownMenuItem>
        <DropdownMenuItem>Settings</DropdownMenuItem>
        <DropdownMenuItem>Billing</DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem>Logout</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

🔹 Toast Notifications

Display temporary notifications with the Toast component. Toasts are perfect for success messages, errors, and informational alerts that don't interrupt user workflow.

# Add toast component
npx shadcn@latest add toast
// components/ToastDemo.js
'use client'
import { Button } from "@/components/ui/button"
import { useToast } from "@/components/ui/use-toast"

export default function ToastDemo() {
  const { toast } = useToast()
  
  return (
    <div className="space-x-2">
      <Button
        onClick={() => {
          toast({
            title: "Success!",
            description: "Your changes have been saved.",
          })
        }}
      >
        Show Toast
      </Button>
      
      <Button
        variant="destructive"
        onClick={() => {
          toast({
            variant: "destructive",
            title: "Error",
            description: "Something went wrong.",
          })
        }}
      >
        Show Error
      </Button>
    </div>
  )
}

🔹 Data Table

Build powerful data tables with sorting, filtering, and pagination. Shadcn/UI tables integrate with TanStack Table for advanced features like column resizing and row selection.

# Add table component
npx shadcn@latest add table
// components/UsersTable.js
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"

const users = [
  { id: 1, name: "John Doe", email: "[email protected]", role: "Admin" },
  { id: 2, name: "Jane Smith", email: "[email protected]", role: "User" },
  { id: 3, name: "Bob Johnson", email: "[email protected]", role: "User" },
]

export default function UsersTable() {
  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {users.map((user) => (
          <TableRow key={user.id}>
            <TableCell>{user.name}</TableCell>
            <TableCell>{user.email}</TableCell>
            <TableCell>{user.role}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

🧠 Test Your Knowledge

What makes Shadcn/UI different from other component libraries?