- Published on
To ShadCN or Not to ShadCN - A Developer's Take
- Authors
- Name
- Thomas Quan
- Reading time
Reading time
5 min read
But first what is ShadCN anyway?
ShadCN is basically a collection of reusable UI components that you can copy-paste into your project. Unlike traditional UI libraries where you install the entire thing and use only a part or most of it. Instead, it's a set of components you can pick and choose from to inject, giving you full control over the code and styling to an extend.
The setup is straightforward as of now (2024-2025). Just visit ShadCN Installation Doc and follow their guide. For example, if you're using pnpm
and want to add their Card component:
pnpm dlx shadcn@latest add card
That's it! No complex configuration or dependencies to manage and now you have a Card component that you can use. It follows the motto of "Pick your Posion".
The Caveat & The Structure It Enforces
ShadCN introduces a specific way of organizing your code. While some parts are flexible, others are required for the components to work properly.
1. Import File Location
By default, ShadCN expects you to:
- Import components from a dedicated function into a specific folder
- Store injected components in a designated location
- Use their CN function to merge styles together
The good news (kinda) ? You can customize both locations. For example, if you want to change the default cn
utility function location from lib/utils.ts
, you can do this:
// Instead of the default location
import { cn } from '@/lib/utils'
// You can move it to
import { cn } from '@/utils/className'
// or
import { cn } from '@/helpers/style'
But it require you to manually do it, there is no CLI installation config to say where you want it to be from what I can find.
2. Component Structure
ShadCN uses a specific component pattern that you'll need to follow. Their components are built using:
- Radix UI primitives for accessibility, low-level primitives design and UX (modals, dropdowns, popovers)
- Tailwind CSS for utility-first styling
- Lucide for icons
- A compound component pattern that favors composability
While you can't change their base component structure, you can extend it. For instance, if you prefer props-based variants instead of their compound component pattern, you can choose to rejig the entire component to achieve your result:
// ShadCN's way
<Card.Root>
<Card.Header>...</Card.Header>
<Card.Content>...</Card.Content>
</Card.Root>
// Your way (with some work)
<Card variant="default" header="..." content="...">
3. Hidden Dependencies ( and the "Bloat" Debate)
While ShadCN itself is not a monolithic library where you need to install everything, it does instead rely on other UI packages under the hood to function properly. Things such as Radix UI, Lucide, Tailwind CSS and Class variance authority are install when you choose to use ShadCN.
This does cause some restriction and limitation to your choices of packages such as:
- No code ownership as it is abstracted away into other packages
- Unable to fully decouple them if later on in time you find that it doesn't meet your need
But it is done so to help offload the complexity of building, testing, and maintaining these to a more well suited team. This way ShadCN can keep it core functionality clean and concise.
Best MVP for building MVP
After months of using ShadCN in both React and Svelte projects, here's what I've learned:
- Speed: You can build functional UIs 10x faster than starting from scratch
- Focus: More time for business logic and backend development
- Consistency: Components follow a consistent pattern and styling
I have found myself being able to demo my photo.thomasquan.dev in a span of a few weeks using just ShadCN + Prisma + Next.js 14 which mind blown me because initially I thought it would take me 6 months to build as I need to scope out the UIs and backend. More details about this project found in photo-cms
The Good Parts
- ✅ Quick to set up and use
- ✅ Full control over component code
- ✅ No unnecessary dependencies
- ✅ Great for prototyping and MVPs
- ✅ Built on solid foundations (Radix UI + Tailwind)
The Not-So-Good Parts
- ❌ Fixed component structure
- ❌ Limited customization without extra work
- ❌ Might feel repetitive after a while
- ❌ Not ideal for highly customized UIs
When to Use ShadCN
Perfect For:
- Quick prototypes
- MVPs
- Learning projects
- Admin dashboards
- Projects with standard UI needs
Maybe Skip For:
- Large enterprise applications
- Projects with unique design requirements
- Apps that need heavy UI customization
- Projects where stakeholder requirements change frequently
Conclusion
ShadCN is a great tool for rapid development and prototyping. It's perfect when you need to:
- Build something quickly
- Focus on business logic
- Create consistent UIs
- Learn modern component patterns
However, for large-scale projects or highly customized applications, you might want to consider building your own component library or using a more flexible solution. The key is to match the tool to your project's needs, not the other way around.
Remember: ShadCN is a tool, not a rule. Use it when it makes sense, and don't be afraid to build your own components when you need something different.