---
name: styling-with-shadcn
description: Build beautiful, accessible UIs with shadcn/ui components in Next.js. Use when creating forms, dialogs, tables, sidebars, or any UI components. Covers installation, component patterns, react-hook-form + Zod validation, and dark mode setup. NOT when building non-React applications or using different component libraries.
---
# shadcn/ui
Build beautiful, accessible UIs with copy-paste components built on Radix UI and Tailwind CSS.
## Quick Start
```bash
# Initialize shadcn/ui in your Next.js project
npx shadcn@latest init
# Add components as needed
npx shadcn@latest add button form dialog table sidebar
```
## Common Component Install
```bash
npx shadcn@latest add button card form input label dialog \
table badge sidebar dropdown-menu avatar separator \
select textarea tabs toast sonner
```
---
## Core Patterns
### 1. Button Variants
```tsx
import { Button } from "@/components/ui/button"
// Sizes: sm, default, lg, icon
// Loading state
// As Next.js Link
```
### 2. Forms with react-hook-form + Zod
```tsx
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
const schema = z.object({
title: z.string().min(1, "Required"),
priority: z.enum(["low", "medium", "high"]),
})
export function TaskForm({ onSubmit }) {
const form = useForm({
resolver: zodResolver(schema),
defaultValues: { title: "", priority: "medium" },
})
return (
)
}
```
See [references/component-examples.md](references/component-examples.md) for complete form with Select, Textarea.
### 3. Dialog / Modal
```tsx
import {
Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger
} from "@/components/ui/dialog"
// Controlled dialog
const [open, setOpen] = useState(false)
```
### 4. Alert Dialog (Confirmation)
```tsx
import {
AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
AlertDialogDescription, AlertDialogFooter, AlertDialogHeader,
AlertDialogTitle, AlertDialogTrigger
} from "@/components/ui/alert-dialog"
Are you sure?
This action cannot be undone.
Cancel
Delete
```
### 5. Data Table (TanStack)
```tsx
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
const columns: ColumnDef[] = [
{ accessorKey: "title", header: "Title" },
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {row.getValue("status")},
},
]
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
```
See [references/component-examples.md](references/component-examples.md) for full DataTable with sorting/pagination.
### 6. Card Component
```tsx
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
{task.title}
Assigned to {task.assignee}
{task.description}
```
### 7. Toast Notifications (Sonner)
```tsx
// Add Toaster to layout
import { Toaster } from "@/components/ui/sonner"
// Use in components
import { toast } from "sonner"
toast.success("Task created")
toast.error("Failed to create task")
toast("Task Updated", { description: "Status changed to in progress" })
toast.promise(createTask(data), {
loading: "Creating...",
success: "Created!",
error: "Failed",
})
```
### 8. Sidebar Navigation
```tsx
import {
Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent,
SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger
} from "@/components/ui/sidebar"
{items.map((item) => (
{item.title}
))}
{children}
```
See [references/component-examples.md](references/component-examples.md) for full sidebar with persistent state.
### 9. Dark Mode
```tsx
// npm install next-themes
// components/theme-provider.tsx
"use client"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({ children, ...props }) {
return {children}
}
// layout.tsx
{children}
// Theme toggle
import { useTheme } from "next-themes"
const { setTheme } = useTheme()
setTheme("dark") // or "light" or "system"
```
---
## Dependencies
```json
{
"dependencies": {
"@hookform/resolvers": "^3.x",
"@radix-ui/react-*": "latest",
"@tanstack/react-table": "^8.x",
"class-variance-authority": "^0.7.x",
"clsx": "^2.x",
"lucide-react": "^0.x",
"next-themes": "^0.4.x",
"react-hook-form": "^7.x",
"sonner": "^1.x",
"tailwind-merge": "^2.x",
"zod": "^3.x"
}
}
```
---
## Verification
Run: `python3 scripts/verify.py`
Expected: `✓ styling-with-shadcn skill ready`
## If Verification Fails
1. Check: references/ folder exists with component-examples.md
2. **Stop and report** if still failing
## Related Skills
- **fetching-library-docs** - Latest shadcn/ui docs: `--library-id /shadcn-ui/ui --topic components`
- **building-nextjs-apps** - Next.js 16 patterns for app structure
## References
- [references/component-examples.md](references/component-examples.md) - Full code examples
- [references/taskflow-theme.md](references/taskflow-theme.md) - Custom theme configuration