Build Failures That Will Ruin Your Day

Build Error Console

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.

Build Errors - Quick Fixes

Q

Why does my build fail with "IconLeft does not exist" in Calendar?

A

This is the most reported shadcn/ui bug. The Calendar component's TypeScript types get out of sync with react-day-picker updates.bash# Nuclear option that always worksrm components/ui/calendar.tsxnpx shadcn@latest add calendarPin react-day-picker to whatever version works in your package.json to prevent this from happening again.

Q

My CLI commands stopped working after upgrading Node.js

A

The shadcn CLI breaks with Node.js 20+ and npm 10+. You'll get certificate errors or module resolution failures.```bash# Check your versions first

  • use Node 18 if possiblenode --versionnpm --version# Fix certificate issuesnpm config set strict-ssl falsenpx shadcn@latest add buttonnpm config set strict-ssl true```
Q

Build works locally but fails in Docker/CI

A

Your local Node.js version differs from production.

Most CI systems use Node 20+, but shadcn/ui works best with Node 18.```dockerfile# Dockerfile

  • Use Node 18FROM node:18-alpine# Rest of your build``````yaml# GitHub Actions
  • Pin Node version
  • uses: actions/setup-node@v4 with: node-version: '18.x'```
Q

TypeScript can't find my components after adding them

A

Your import paths are fucked.

The CLI assumes you use @/ aliases but your project doesn't have them configured.```json// tsconfig.json

  • Add these paths{"compilerOptions": {"baseUrl": ".","paths": {"@/": ["./src/"]}}}```
Q

Components work in dev but break in production build

A

Tailwind CSS is purging the classes shadcn/ui uses. Tailwind can't see the dynamically constructed class names, so it thinks they're unused and strips them out.Add this to your tailwind.config.js:javascriptmodule.exports = { content: [ './src/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', ], safelist: [ 'data-[state=open]:animate-in', 'data-[state=closed]:animate-out' ]}

Q

Why do my builds take 5+ minutes now?

A

You're importing entire icon libraries. The build process has to analyze thousands of unused icons.```typescript// Slow

  • imports entire libraryimport * as Icons from '@radix-ui/react-icons'// Fast
  • imports one iconimport { CheckIcon } from '@radix-ui/react-icons'```

Hydration Errors - The SSR Nightmare

Hydration Mismatch Console

Hydration mismatches will kill your Next.js app in production. The server renders one thing, the client renders another, and React loses its shit. Here's what actually causes them and how to fix them without disabling SSR entirely.

Theme Provider Hydration Hell

Error Message:

Hydration failed because the initial UI does not match what was rendered on the server.

The most common shadcn/ui hydration error comes from the ThemeProvider component. Server renders in light mode, client mounts in dark mode, React explodes.

Root Cause: next-themes tries to read localStorage during SSR, which doesn't exist on the server.

Working Fix - Suppress Hydration Warnings:

// app/layout.tsx
import { ThemeProvider } from '@/components/theme-provider'

export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}

The suppressHydrationWarning on the html tag prevents the theme mismatch error. It's not elegant, but it's the only solution that actually works.

Dialog Component Hydration Failures

Error: Dialog components render closed on server, open on client.

Problem: useState and useEffect cause server/client mismatches.

Fix - Dynamic Import with No SSR:

// components/dialog-wrapper.tsx
import dynamic from 'next/dynamic'

const Dialog = dynamic(
  () => import('@/components/ui/dialog').then(mod => mod.Dialog),
  { 
    ssr: false,
    loading: () => <div className="animate-pulse h-10 bg-gray-200" />
  }
)

export { Dialog }

This prevents the dialog from rendering on the server at all. You lose SSR benefits but gain working components.

Form Components Lose Focus

Issue: Input fields lose focus after hydration, making forms unusable.

Cause: React can't match server-rendered id attributes with client-generated ones.

Fix - Stable IDs:

// components/ui/form-field.tsx
import { useId } from 'react'

export function FormField({ children }) {
  // Use React's useId for stable server/client IDs
  const id = useId()
  
  return (
    <div>
      <label htmlFor={id}>Name</label>
      <input id={id} name="name" />
    </div>
  )
}

useId() generates the same ID on server and client, preventing hydration mismatches.

Toast Notifications Disappear

Problem: Toasts show on server render, disappear immediately after hydration.

Fix - Client-Only Toasts:

// components/toast-wrapper.tsx
'use client'

import { useEffect, useState } from 'react'
import { Toaster } from '@/components/ui/toast'

export function ToastWrapper() {
  const [mounted, setMounted] = useState(false)
  
  useEffect(() => {
    setMounted(true)
  }, [])
  
  if (!mounted) return null
  
  return <Toaster />
}

Only render toasts after the client has mounted. No server/client mismatch possible.

Next.js 15 Hydration Breaking Changes

Next.js 15 made hydration stricter. Components that worked in 14.x now throw hydration errors.

Specific Breaking Changes:

  • use client components are hydrated earlier
  • Suspense boundaries behave differently
  • React 19's concurrent features cause timing issues

Working Next.js 15 Setup:

// next.config.js
module.exports = {
  reactStrictMode: false, // Disable for shadcn/ui compatibility
  experimental: {
    ppr: false, // Partial prerendering breaks dialogs
  }
}

React Strict Mode + shadcn/ui = guaranteed hydration hell. Just turn the damn thing off.

Component State Persistence Issues

Error: Component state resets after hydration.

Problem: Server and client render different initial states.

Fix - Persistent State Pattern:

'use client'

import { useState, useEffect } from 'react'

export function StatefulComponent() {
  const [state, setState] = useState(() => {
    // Only access localStorage after mount
    if (typeof window === 'undefined') return defaultState
    return localStorage.getItem('key') || defaultState
  })
  
  useEffect(() => {
    // Sync state after hydration
    const saved = localStorage.getItem('key')
    if (saved && saved !== state) {
      setState(saved)
    }n  }, [])
  
  return <div>{state}</div>
}

This pattern ensures server renders the default state, then updates the client state after hydration completes.

The Nuclear Option - Disable SSR

When all else fails and you need to ship:

// components/client-only.tsx
import dynamic from 'next/dynamic'

const ClientOnly = dynamic(() => Promise.resolve(({ children }) => <>{children}</>), {
  ssr: false
})

// Usage - wrap problematic components
<ClientOnly>
  <ProblematicShadcnComponent />
</ClientOnly>

You lose SEO benefits and initial load performance, but your app actually works. Sometimes that's more important than perfect SSR. Used this to fix a checkout flow that was completely broken - everything else we tried just made it worse.

Runtime Errors - When Components Break

Q

My Dialog won't close in production but works in dev

A

Classic Next.js hydration issue.

The Dialog state gets fucked during server/client handoff.```tsx// Quick fix

  • disable SSR for dialogsimport dynamic from 'next/dynamic'const Dialog = dynamic(() => import('@/components/ui/dialog'), { ssr: false })```
Q

Theme switching causes white flash in production

A

The ThemeProvider reads localStorage which doesn't exist during SSR. This causes a theme mismatch.```tsx// app/layout.tsx

  • suppress the hydration warning {children} ```
Q

Form inputs lose focus after page load

A

React can't match server-generated IDs with client IDs. Use useId() for stable identifiers.tsximport { useId } from 'react'function FormField() { const id = useId() return <input id={id} />}

Q

Toasts appear then immediately disappear

A

Toast state gets reset during hydration. Only render toasts after client mount.ts'use client'import { useEffect, useState } from 'react'export function ToastProvider() { const [mounted, setMounted] = useState(false) useEffect(() => setMounted(true), []) return mounted ? <Toaster /> : null}

Q

Components work in Next.js 14 but break in Next.js 15

A

React 19 + Next.js 15 changed hydration behavior. Turn off strict mode and partial prerendering.javascript// next.config.jsmodule.exports = { reactStrictMode: false, experimental: { ppr: false }}

Q

Bundle size exploded after adding shadcn/ui components

A

You're importing entire icon libraries. Check your bundle analyzer and fix the imports.```bash# See what's bloating your bundlenpx @next/bundle-analyzer``````typescript// Bad

  • imports 500KB of iconsimport * as Icons from 'lucide-react'// Good
  • imports 2KBimport { CheckIcon } from 'lucide-react'}```
Q

Components render fine but styling is broken in production

A

Tailwind CSS purged the classes shadcn/ui needs. Add the dynamic classes to your safelist.javascript// tailwind.config.jsmodule.exports = { safelist: [ 'data-[state=open]:animate-in', 'data-[state=closed]:animate-out' ]}

Essential Debugging Resources

Related Tools & Recommendations

integration
Similar content

Stripe Next.js Serverless Performance: Optimize & Fix Cold Starts

Cold starts are killing your payments, webhooks are timing out randomly, and your users think your checkout is broken. Here's how to fix the mess.

Stripe
/integration/stripe-nextjs-app-router/serverless-performance-optimization
100%
tool
Similar content

React Production Debugging: Fix App Crashes & White Screens

Five ways React apps crash in production that'll make you question your life choices.

React
/tool/react/debugging-production-issues
81%
compare
Recommended

Framework Wars Survivor Guide: Next.js, Nuxt, SvelteKit, Remix vs Gatsby

18 months in Gatsby hell, 6 months testing everything else - here's what actually works for enterprise teams

Next.js
/compare/nextjs/nuxt/sveltekit/remix/gatsby/enterprise-team-scaling
76%
tool
Similar content

TaxBit Enterprise Production Troubleshooting: Debug & Fix Issues

Real errors, working fixes, and why your monitoring needs to catch these before 3AM calls

TaxBit Enterprise
/tool/taxbit-enterprise/production-troubleshooting
59%
tool
Similar content

SolidJS: React Performance & Why I Switched | Overview Guide

Explore SolidJS: achieve React-like performance without re-renders. Learn why I switched from React, what it is, and advanced features that save time in product

SolidJS
/tool/solidjs/overview
57%
troubleshoot
Similar content

Fix Slow Next.js Build Times: Boost Performance & Productivity

When your 20-minute builds used to take 3 minutes and you're about to lose your mind

Next.js
/troubleshoot/nextjs-slow-build-times/build-performance-optimization
57%
tool
Similar content

Fix TaxAct Errors: Login, WebView2, E-file & State Rejection Guide

The 3am tax deadline debugging guide for login crashes, WebView2 errors, and all the shit that goes wrong when you need it to work

TaxAct
/tool/taxact/troubleshooting-guide
57%
tool
Similar content

Arbitrum Production Debugging: Fix Gas & WASM Errors in Live Dapps

Real debugging for developers who've been burned by production failures

Arbitrum SDK
/tool/arbitrum-development-tools/production-debugging-guide
53%
troubleshoot
Similar content

React Performance Optimization: Fix Slow Loading & Bad UX in Production

Fix slow React apps in production. Discover the top 5 performance killers, get step-by-step optimization fixes, and learn prevention strategies for faster loadi

React
/troubleshoot/react-performance-optimization-production/performance-optimization-production
51%
tool
Similar content

PostgreSQL: Why It Excels & Production Troubleshooting Guide

Explore PostgreSQL's advantages over other databases, dive into real-world production horror stories, solutions for common issues, and expert debugging tips.

PostgreSQL
/tool/postgresql/overview
47%
tool
Similar content

Debugging AI Coding Assistant Failures: Copilot, Cursor & More

Your AI assistant just crashed VS Code again? Welcome to the club - here's how to actually fix it

GitHub Copilot
/tool/ai-coding-assistants/debugging-production-failures
47%
integration
Recommended

I Spent a Weekend Integrating Clerk + Supabase + Next.js (So You Don't Have To)

Because building auth from scratch is a fucking nightmare, and the docs for this integration are scattered across three different sites

Supabase
/integration/supabase-clerk-nextjs/authentication-patterns
44%
review
Recommended

Vite vs Webpack vs Turbopack: Which One Doesn't Suck?

I tested all three on 6 different projects so you don't have to suffer through webpack config hell

Vite
/review/vite-webpack-turbopack/performance-benchmark-review
44%
tool
Recommended

Vite - Build Tool That Doesn't Make You Wait

Dev server that actually starts fast, unlike Webpack

Vite
/tool/vite/overview
44%
tool
Similar content

AWS CodeBuild Overview: Managed Builds, Real-World Issues

Finally, a build service that doesn't require you to babysit Jenkins servers

AWS CodeBuild
/tool/aws-codebuild/overview
43%
tool
Similar content

Alpine.js Overview: A Lightweight JavaScript Framework for Modern Web

Discover Alpine.js, the lightweight JavaScript framework that simplifies frontend development. Learn why it exists, its core directives, and how it offers a ref

Alpine.js
/tool/alpine-js/overview
43%
tool
Similar content

Webpack: The Build Tool You'll Love to Hate & Still Use in 2025

Explore Webpack, the JavaScript build tool. Understand its powerful features, module system, and why it remains a core part of modern web development workflows.

Webpack
/tool/webpack/overview
43%
compare
Recommended

Remix vs SvelteKit vs Next.js: Which One Breaks Less

I got paged at 3AM by apps built with all three of these. Here's which one made me want to quit programming.

Remix
/compare/remix/sveltekit/ssr-performance-showdown
42%
tool
Recommended

Remix - HTML Forms That Don't Suck

Finally, a React framework that remembers HTML exists

Remix
/tool/remix/overview
42%
tool
Similar content

Apollo GraphQL Overview: Server, Client, & Getting Started Guide

Explore Apollo GraphQL's core components: Server, Client, and its ecosystem. This overview covers getting started, navigating the learning curve, and comparing

Apollo GraphQL
/tool/apollo-graphql/overview
41%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization