I've used them all. Material UI, Chakra, Ant Design, Mantine. They all share the same problem: when you need to customize something beyond the provided props, you fight the library.
Override styles? Specificity wars. Custom behavior? Fork the component. Different design language? Good luck theming a library that was designed for Material Design.
It's not a library you install. It's a collection of components you copy into your project. You own the code. You modify it directly. There's no abstraction layer between you and the DOM.
npx shadcn@latest add button dialog form tableThis copies the component source into src/components/ui/. Need to change the button's border radius? Edit the file. Need a custom variant? Add it.
Every client has different design requirements. With a traditional component library, customization is:
!important or CSS hacksWith shadcn/ui:
Under the hood, shadcn/ui components use Radix UI primitives for accessibility and behavior. This means you get:
All without thinking about it. The accessible behavior is baked into the primitives. You just style the surface.
Across all my projects, these get used on every build:
shadcn/ui has become the de facto standard for React projects. The community contributes new components regularly, and the CLI makes adding them frictionless. It's the first thing I install on every new project.