The Case Against Default Component Libraries
Shadcn is excellent. Radix is excellent. Headless UI is excellent.
Their defaults are the problem.
The Default Epidemic
Every component library ships with sensible defaults. Border radii. Button sizes. Form styles. These defaults are designed to look acceptable immediately.
Acceptable is the enemy of distinctive.
When you ship with defaults, you look like everyone else who shipped with defaults. Same rounded corners. Same gray borders. Same hover states.
"Your product becomes a template. Users have seen it a thousand times. They recognize the components, not your brand."
The problem has accelerated. Shadcn's UI registry now serves millions of downloads. Every Next.js tutorial starts with the same component installation. The result is a generation of products that share identical DNA.
Why Developers Don't Customize
Customization takes time. You have to override every variable, adjust every spacing value, rethink every animation.
Most developers don't bother. They're shipping features. The button looks fine. The dropdown works. Why change it?
Because looking the same costs you something.
Steve Schoger, co-author of Refactoring UI, puts it directly: "Default components are for prototyping. If you ship them to production unchanged, you're telling users you didn't care enough to make choices."
The cost shows up in conversion rates. In pricing ceilings. In the inability to command a premium.
The Shadcn Tell
There's a specific look that screams "shadcn defaults":
- 6px or 8px border radius everywhere - Gray borders at low opacity - Subtle black shadows - System font or Inter - Ring focus states in slate or gray - Muted accent colors
This is a fine aesthetic. It's also invisible. Users don't notice it because they've seen it everywhere.
Dan Mall, design system consultant and author of Design That Scales, observed: "When I audit startups, I can identify which component library they used within 30 seconds. That means their product has no visual identity of its own."
"Customization isn't decoration. It's definition. Every visual decision you make—or don't make—is a brand decision."
What to Override
At minimum, customize these five elements:
1. Accent Color
Replace the default blue with your brand color. Apply it to: - Primary buttons - Text links - Focus rings - Selected states - Progress indicators2. Border Radius
Pick a number and apply it consistently. - 0px for sharp, technical brands - 4px for subtle, professional brands - 8px for soft, friendly brands - 16px+ for playful, consumer brands3. Font Stack
Replace system fonts with your brand fonts. This single change has outsized impact.4. Focus States
Make focus rings match your accent color. Default gray focus states feel unbranded.5. Hover Animations
Adjust timing and easing to feel right for your personality. Snappy for technical brands. Smooth for premium brands.The Compound Effect
These five overrides compound. Every future component inherits your decisions. New pages look consistent without extra effort.
Vercel customizes their use of component primitives extensively. Their dark theme, specific border radii, and custom animations create a distinctive experience despite using common underlying libraries.
Linear does the same. Their components are built on headless primitives, but every visual property is intentionally chosen.
"Use the library for structure. Apply your brand for personality."
The component library handles accessibility, keyboard navigation, and interaction patterns. Your brand handles everything visual.
The CSS Variables Approach
Most component libraries now support CSS variable theming. This makes customization systematic rather than ad-hoc.
In shadcn, you can override via globals.css:
:root {
--radius: 4px;
--primary: 15 80% 40%;
--ring: 15 80% 40%;
}
This propagates through every component automatically.
The investment is upfront. The returns are ongoing.
Don't Start From Scratch
This isn't an argument against component libraries. They're valuable. They save time. They handle accessibility.
The argument is against accepting their defaults unchanged.
"The components should look like they belong to your product, not to a tutorial."
Loom's interface is built on component primitives but feels distinctly Loom. Raycast's interface uses common patterns but feels distinctly Raycast.
The difference is intent. They made choices. They locked those choices. They applied them everywhere.
Your components should feel the same way.
---Ready to customize your components? Try the Vox Animus demo to define your visual direction first.