Your CI/CD just failed. Again. shadcn/ui builds fine locally but explodes in production. Here's what's actually breaking and how to fix it without losing your mind.
The Calendar IconLeft/IconRight TypeScript Nightmare
Error Message:
Type error: Object literal may only specify known properties, and 'IconLeft' does not exist in type 'Partial<CustomComponents>'.
This specific bug hits randomly and will destroy your production build. The Calendar component's TypeScript definitions get out of sync with the actual props - happened to me when we were trying to ship some feature, I think it was late in the week.
Nuclear Fix:
## Delete and reinstall the component
rm -rf components/ui/calendar.tsx
npx shadcn@latest add calendar
Root Cause:
The react-day-picker types randomly break when they update their interfaces. Pretty sure this was around version 8.10 or something.
Production Prevention:
// package.json - Pin whatever version works for you
{
"dependencies": {
"react-day-picker": "8.10.1" // Don't let this auto-update
}
}
Next.js 15 + React 19 Build Explosions
Next.js 15 breaks half the shadcn/ui components due to React 19 changes. Your build will fail with cryptic errors about forwardRef
and displayName
.
What Breaks:
- Dialog components throw hydration errors
- Form components lose focus management
- Toast notifications disappear immediately
- Theme providers cause SSR mismatches
Working Fix:
Use Next 15, React 19, and whatever Radix versions don't explode. Check shadcn/ui's React 19 compatibility table before upgrading anything. Learned this the hard way after spending way too much time debugging hydration errors.
ESLint Version Hell
Error that appears:
Module not found: Can't resolve '@typescript-eslint/parser'
ESLint 9+ completely fucks up the CLI. Spent forever figuring out it was expecting the old config format or some shit.
ESLint versions that don't break everything:
Stay on ESLint 8.x for now. Don't upgrade to v9 until shadcn/ui catches up. I've seen this kill builds multiple times recently.
TypeScript Module Resolution Chaos
Error Message:
Cannot find module '@/components/ui/button' or its corresponding type declarations.
This happens when your tsconfig.json
paths don't match what shadcn/ui expects.
Fix Your tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"]
},
"moduleResolution": "node"
}
}
The CLI assumes you're using @/
aliases. If you're not, either set them up or manually fix all the imports after adding components. This gotcha got me good.
Tailwind CSS Purge Issues
Your production build strips out necessary Tailwind classes, breaking component styling.
Problem:
Tailwind's purge process doesn't detect dynamically constructed classes in shadcn/ui components.
Fix - Update tailwind.config.js:
// Add your component paths and safelist the animation classes
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
safelist: [
'data-[state=open]:animate-in',
'data-[state=closed]:animate-out',
// Add other animation classes as needed
]
}
Bundle Size Explosion
shadcn/ui + Tailwind can bloat your bundle to 2MB+ if you're not careful.
Bundle Analysis:
## See what's actually in your bundle
npx @next/bundle-analyzer
Bundle Optimizations:
// next.config.js - optimize icon imports
module.exports = {
experimental: {
optimizePackageImports: ['lucide-react', '@radix-ui/react-icons']
}
}
Remove Unused Icons:
Don't import entire icon libraries. Use specific imports or you'll bundle everything.
Your bundle analyzer will show icon libraries taking up way too much space. Took me forever to realize all those icons were getting bundled. Fix the imports.