Add @shadcn/ui components to your app.
@shadcn/ui is a component distribution system that fundamentally differs from traditional UI libraries. Rather than installing components as an npm dependency, you use a CLI tool to copy source code directly into your project. This gives you complete ownership over the components, allowing unrestricted modification without fighting against library abstractions or waiting for upstream fixes.
The components are built on Radix UI primitives for accessibility and headless functionality, styled with Tailwind CSS utility classes. When you run commands like npx shadcn-ui@latest add button, the CLI downloads the component source into your project's components directory. You can then modify the code however you need—change the styling, add props, refactor the structure—because it's your code now, not a black-box import from node_modules.
This approach solves real problems developers face with packaged component libraries: style conflicts, inflexible APIs, bundle bloat from unused components, and the inability to fix bugs without forking entire repositories. shadcn/ui is particularly popular among developers building design systems, MVPs, or applications requiring heavy component customization. The system has gained significant traction with over 83,000 weekly CLI downloads, reflecting its adoption in modern React projects where developer control and flexibility matter more than convenience.
The CLI handles initial setup, configuring Tailwind, installing Radix UI dependencies, and setting up your components directory structure. After initialization, each component you add brings its own dependencies, but you manage them explicitly in your package.json rather than inheriting a monolithic library's entire dependency tree.
// 1. Initialize shadcn/ui in your React project
// npx shadcn-ui@latest init
// 2. Add components you need
// npx shadcn-ui@latest add button form input
// 3. Use and customize components in your app
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
const formSchema = z.object({
email: z.string().email('Invalid email address'),
username: z.string().min(3, 'Username must be at least 3 characters'),
});
export function SignupForm() {
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: { email: '', username: '' },
});
function onSubmit(values) {
console.log('Form submitted:', values);
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="johndoe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="john@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Create Account</Button>
</form>
</Form>
);
}Building Custom Design Systems: Copy shadcn/ui components as starting points and modify them to match your brand guidelines, color palettes, and interaction patterns without abstraction layers limiting your changes.
Rapid Prototyping with Future Flexibility: Quickly scaffold interfaces with pre-built accessible components, knowing you can refactor or completely rewrite them later without migration pain since they live in your codebase.
Form-Heavy Applications: Utilize the Form component's React Hook Form and Zod integration for type-safe form validation in admin panels, user onboarding flows, or data entry applications where complex validation rules are required.
Bundle Size Optimization: Add only the exact components you need rather than importing entire UI libraries, crucial for performance-sensitive applications or projects with strict bundle size requirements.
AI-Assisted Development: Leverage the consistent code structure to let AI tools like Cursor or GitHub Copilot understand and generate variations of components, or use tools like v0.dev to AI-generate component modifications based on your existing shadcn/ui patterns.
npm install @shadcn/uipnpm add @shadcn/uibun add @shadcn/ui