DEV Community

Alex Spinov
Alex Spinov

Posted on

shadcn/ui Has Free Components: Copy-Paste React Components You Own — No npm Package, No Vendor Lock-In

Material UI adds 200KB to your bundle. Chakra UI forces its theming system. Ant Design looks like every other enterprise app. You install a component library and spend more time fighting its opinions than building features.

What if UI components were just files in YOUR project? No npm dependency. No version conflicts. No abstraction layers.

That's shadcn/ui. You don't install it — you copy it. Each component is a file you own and modify.

How It Works

npx shadcn@latest init
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add form
Enter fullscreen mode Exit fullscreen mode

Each command copies a component file into components/ui/. You own it. Edit it. Delete it. No node_modules dependency.

What You Get

components/ui/
  button.tsx        ← you own this
  dialog.tsx        ← you own this
  input.tsx         ← you own this
  form.tsx          ← you own this
  toast.tsx         ← you own this
  dropdown-menu.tsx ← you own this
Enter fullscreen mode Exit fullscreen mode

Usage

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { 
  Dialog, DialogContent, DialogHeader, 
  DialogTitle, DialogTrigger 
} from "@/components/ui/dialog";

function ContactForm() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="outline">Contact Us</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Send a Message</DialogTitle>
        </DialogHeader>
        <form className="space-y-4">
          <Input placeholder="Your name" />
          <Input type="email" placeholder="Email" />
          <Button type="submit" className="w-full">Send</Button>
        </form>
      </DialogContent>
    </Dialog>
  );
}
Enter fullscreen mode Exit fullscreen mode

Built on Radix + Tailwind

Under the hood, shadcn/ui uses:

  • Radix UI — accessible, unstyled headless primitives (keyboard nav, ARIA, focus management)
  • Tailwind CSS — utility-first styling you customize via tailwind.config
  • class-variance-authority — type-safe component variants
// components/ui/button.tsx — what you actually own
const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
  {
    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",
        secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      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",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
);
Enter fullscreen mode Exit fullscreen mode

Want a new variant? Add 2 lines. No PRs to an npm package. No waiting for releases.

Theming With CSS Variables

/* globals.css */
@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 222.2 47.4% 11.2%;
    --primary-foreground: 210 40% 98%;
    /* Change these → entire app re-themes */
  }
  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
  }
}
Enter fullscreen mode Exit fullscreen mode

shadcn/ui vs Component Libraries

Feature shadcn/ui Material UI Chakra UI
Installation Copy files npm package npm package
Bundle impact Only what you use 200KB+ 150KB+
Customization Edit source Override themes Override themes
Upgrade path Manual Breaking changes Breaking changes
Accessibility Radix (excellent) Built-in Built-in
Tailwind-native Yes No No

When to Choose shadcn/ui

Choose shadcn/ui when:

  • You use Tailwind CSS and want matching components
  • You want full control over component code
  • Bundle size matters (only include what you use)
  • You want accessible components without runtime overhead

Skip shadcn/ui when:

  • You don't use Tailwind CSS
  • You want pre-built complex components (data grids, charts) out of the box
  • Your team prefers a traditional npm package lifecycle

The Bottom Line

shadcn/ui isn't a component library — it's a component collection you own. Copy what you need, customize it, ship it. No dependency updates. No breaking changes. No vendor lock-in.

Start here: ui.shadcn.com


Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors

Top comments (0)