Solución de problemas comunes de shadcn/ui: conflictos de estilos, componentes que no renderizan y errores de tipos

Miras el botón en pantalla: debería ser un botón azul elegante, pero parece un <button> HTML cualquiera, sin ni siquiera bordes redondeados.
En los últimos tres meses he tropezado con más problemas que líneas de código útiles. Conflictos de estilos, componentes que no renderizan, errores de TypeScript: casi forman parte del «paquete» de shadcn/ui, y en cada proyecto nuevo aparecen uno o dos.
Hoy reúno estos problemas frecuentes y sus soluciones para que evites parte del camino.
Diagnóstico de conflictos de estilos
Los conflictos de estilos son lo más habitual: representan unas cuatro de cada diez incidencias. Las causas principales son estas:
Conflictos de variables CSS
shadcn/ui usa variables CSS para los colores del tema, definidas en globals.css:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 2%;
}
El problema aparece cuando el proyecto ya tenía su propia configuración de tema, o si modificaste los colores de Tailwind antes de instalar shadcn/ui: las dos configuraciones pueden chocar.
¿Cómo diagnosticarlo?
Abre globals.css y comprueba que todas las variables CSS estén presentes. Luego revisa la sección colors de tailwind.config.js:
module.exports = {
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
}
Ambos lados deben corresponderse. Si falta una variable, el estilo asociado no se aplicará.
Mi experiencia: antes de instalar shadcn/ui, respalda tailwind.config.js y globals.css. Tras la instalación, compara ambos archivos y restaura manualmente la configuración que se haya sobrescrito.
Shadow DOM y conflictos con Tailwind
Este caso es curioso. Shadow DOM sirve para aislar estilos, pero las clases de Tailwind no atraviesan su límite.
El escenario típico es el componente Dialog. DialogContent se renderiza con Portal en document.body, fuera del Shadow DOM, y los estilos desaparecen.
Hay dos soluciones:
La primera: no usar Shadow DOM:
const MyDialogWC = r2wc(MyDialog, {
shadow: null // desactivar Shadow DOM
});
Así el Portal funciona, pero pierdes el aislamiento de estilos. Tendrás que gestionar los estilos globales con cuidado y vigilar conflictos de nombres de clase.
La segunda: usar Safelist para forzar la inclusión de clases:
// tailwind.config.js
module.exports = {
safelist: [
'bg-primary',
'text-primary-foreground',
'hover:bg-primary/90',
'bg-red-500',
'h-9',
'h-10',
'px-3',
'px-4',
],
}
Garantiza que se generen los estilos, pero Safelist aumenta el tamaño del CSS. Hay que sopesarlo.
Convivencia con otras bibliotecas de UI
Si el proyecto ya usa MUI (Material-UI) y quieres migrar a shadcn/ui, aparecerán conflictos de estilos.
La raíz está en Preflight de Tailwind: restablece los estilos por defecto del navegador. Los de MUI también se resetean y los componentes se ven mal.
Intentos habituales:
Algunos desactivan Preflight:
module.exports = {
corePlugins: {
preflight: false, // desactivar Preflight
},
}
Pero tiene efectos secundarios: los estilos de Tailwind también se ven afectados y algunos componentes pueden fallar.
Mejor enfoque:
Usa el prefix de Tailwind para prefijar todas las clases:
module.exports = {
prefix: 'tw-', // tw-bg-blue-500 en lugar de bg-blue-500
}
Así las clases de Tailwind no chocan con las de MUI. Tendrás que anteponer tw- manualmente a cada clase, lo cual es algo tedioso.
Mi recomendación: si ya hay muchos componentes MUI, no migres todo de golpe. Usa prefix para convivir: shadcn/ui en lo nuevo y MUI en lo existente, migrando poco a poco.
Configuración de Tailwind sobrescrita
Este problema me ha pillado varias veces.
Tras ejecutar npx shadcn-ui@latest init, el archivo de Tailwind se sobrescribe. Sobre todo el array plugins: si tenías @tailwindcss/forms u otros plugins, desaparecen.
Los síntomas son claros: los inputs del formulario se ven raros de repente, o algunos componentes pierden todo el estilo.
Pasos de diagnóstico:
- Abre el respaldo de
tailwind.config.jsde antes de la instalación - Compara con el archivo actual
- Restaura los plugins que falten:
module.exports = {
// ... resto de configuración
plugins: [
require("@tailwindcss/forms"), // restaurar
require("tailwindcss-animate"),
],
}
Prevención: respalda la configuración antes de instalar shadcn/ui, o usa un script que registre todos los plugins.
Diagnóstico cuando los componentes no renderizan
Los estilos están bien, pero el componente no aparece. También es frecuente.
Rutas content mal configuradas
Tailwind necesita saber en qué archivos se usan sus clases para generar el CSS correspondiente. Eso se define en el campo content de tailwind.config.js.
Lo habitual: el directorio de componentes de shadcn/ui no está incluido.
Revisa la configuración:
module.exports = {
content: [
'./src/app/**/*.{ts,tsx}',
'./src/components/**/*.{ts,tsx}', // imprescindible
'./app/**/*.{ts,tsx}',
'./pages/**/*.{ts,tsx}',
],
}
Si los componentes están en una biblioteca dentro de node_modules, añade también:
content: [
// ... otras rutas
'./node_modules/@your-ui-lib/**/*.{ts,tsx}',
]
Mi experiencia: cada vez que crees un directorio de componentes nuevo, añade la ruta a content. Si Tailwind no escanea esos archivos, no generará las clases.
Problemas con la ruta de globals.css
shadcn/ui necesita un archivo CSS con las variables del tema. La ruta se configura en components.json.
Lo habitual: ruta incorrecta o varios archivos globals.css.
Cómo diagnosticarlo:
Revisa components.json:
{
"style": "default",
"css": "src/app/globals.css", // esta ruta
}
Luego confirma:
- ¿Existe realmente ese archivo?
- ¿Solo hay un
globals.cssen el proyecto? - ¿Se importa correctamente en el archivo principal?
Si hay varios globals.css, elimina los sobrantes y deja uno solo.
Comprobar la importación:
En Next.js, globals.css debe importarse en app/layout.tsx o pages/_app.tsx:
import '@/app/globals.css' // o './globals.css'
Sin importación, las variables CSS no aplican y los componentes pierden el estilo.
Variables CSS sin definir
A veces globals.css existe, pero faltan variables.
Lo típico es el modo oscuro: activas dark mode y los colores no cuadran, quizá porque no configuraste las variables para oscuro.
Revisa globals.css:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 2%;
}
Las variables bajo .dark deben estar definidas. Si no, los componentes en modo oscuro quedan sin estilo.
Caso especial de Tailwind v4:
Con Tailwind v4 la configuración es distinta:
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
}
Ese mapeo @theme inline es obligatorio. Sin él, Tailwind v4 no reconoce esas variables.
Mayúsculas y minúsculas en las rutas de importación
Este fallo me ha costado dos veces.
En Windows los nombres de archivo no distinguen mayúsculas; en Linux/Mac sí. En local todo va bien; en el servidor, error al desplegar.
El síntoma habitual: el componente renderiza en local, pero en producción no encuentra el módulo.
Error típico:
// ❌ incorrecto: B mayúscula en Button
import { Button } from "@/components/ui/Button"
// ✅ correcto: button en minúsculas
import { Button } from "@/components/ui/button"
Los archivos de componentes shadcn/ui están en minúsculas. La ruta de importación también.
Cómo diagnosticarlo:
Revisa todas las importaciones de componentes y comprueba que coincidan con el nombre real del archivo, sobre todo si el error solo aparece en producción.
Diagnóstico de errores de TypeScript
Los errores de TypeScript son menos frecuentes, pero igual de molestos.
Errores de tipo en la prop variant
El Button de shadcn/ui tiene la prop variant para cambiar el estilo (default, destructive, outline, etc.).
El mensaje suele ser:
Type '{ variant: string }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
Property 'variant' does not exist on type 'IntrinsicAttributes & ButtonProps'.
Causa:
En la definición de tipos del Button, la prop variant no se exporta correctamente.
Cómo diagnosticarlo:
Abre components/ui/button.tsx y revisa la definición de variant:
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
},
},
}
)
interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
// VariantProps debe estar aquí
}
Si falta VariantProps<typeof buttonVariants>, desaparece el tipo de variant.
Mi experiencia: ante este error, revisa primero la definición de tipos del componente y confirma que VariantProps se hereda bien.
Incompatibilidad de versiones de React
Con React 19, si alguna dependencia aún no lo soporta, aparecen errores de tipos.
El mensaje suele ser:
npm error ERESOLVE unable to resolve dependency tree
npm error Found: [email protected]
Dos soluciones:
Forzar la instalación:
npm install --legacy-peer-deps
# o
npm install --force
Ignora los requisitos de peer dependency, pero puede haber problemas de compatibilidad.
O bajar la versión de React:
npm install react@18 react-dom@18
Usa React 18 hasta que las dependencias se actualicen.
Mi recomendación: en proyectos nuevos, React 18 es más estable. Pasa a React 19 cuando shadcn/ui y el resto de dependencias lo soporten de forma clara.
Problemas de tipos con React Hook Form
El Form de shadcn/ui con React Hook Form y Zod puede dar errores de mapeo de tipos.
El mensaje suele ser:
Type 'info.${number}.fileName' is not assignable to type '"info" | "info.0" | "info.0.fileName"'
Es un problema de tipos en campos dinámicos: el tipo del schema Zod no coincide con el de la prop name de FormField.
Solución:
Asegura la inferencia correcta del schema:
const formSchema = z.object({
email: z.string().email(),
password: z.string(),
})
type FormValues = z.infer<typeof formSchema> // imprescindible
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
})
La prop name de FormField coincidirá con los campos del schema.
Mi experiencia: los formularios dinámicos (por ejemplo con useFieldArray) son más complejos. Revisa con cuidado el schema Zod y la inferencia de TypeScript.
Dependencias de tipos faltantes
A veces TypeScript falla porque no están instalados @types/react o @types/react-dom.
El mensaje puede ser:
Could not find a declaration file for module 'react'
Solución:
npm install -D @types/react @types/react-dom
Después, reinicia el servidor de TypeScript (en VSCode: Ctrl+Shift+P → «TypeScript: Restart TS Server»).
Prevención: instala las dependencias de tipos desde el inicio del proyecto. No esperes al primer error.
Buenas prácticas y prevención
Tras tantos tropiezos, esto es lo que recomiendo para prevenirlos.
Gestión de la configuración
Respaldar archivos de configuración:
Antes de instalar shadcn/ui o modificar Tailwind:
cp tailwind.config.js tailwind.config.js.backup
cp globals.css globals.css.backup
Tras instalar, compara y fusiona los cambios manualmente.
Un solo archivo de configuración:
Un proyecto, un tailwind.config.js y un globals.css. Varios archivos generan conflictos.
Rutas content completas:
Incluye todos los directorios de componentes:
content: [
'./src/**/*.{ts,tsx}', // comodín para cubrir todo
'./app/**/*.{ts,tsx}',
'./pages/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
]
Gestión de versiones de dependencias
Revisar peerDependencies:
Antes de instalar un paquete nuevo:
npm info <package> peerDependencies
Si exige React 18 y usas React 19, valora la compatibilidad.
Actualizar dependencias de tipos:
npm update @types/react @types/react-dom
Mantén las declaraciones alineadas con la versión de React.
Estrategia de pruebas
Probar justo después de instalar:
Cuando termines de instalar shadcn/ui, prueba los estilos de inmediato:
- Crea una página sencilla con varios componentes shadcn/ui
- Comprueba que los estilos se ven bien
- Prueba el cambio a modo oscuro
- Ejecuta la compilación de TypeScript
Probar en entorno de producción:
Que funcione en local no garantiza producción:
npm run build
npm run preview
Tras el build, previsualiza y verifica estilos y tipos.
Resumen
En la práctica, los problemas habituales de shadcn/ui se concentran en tres áreas:
- Conflictos de estilos: configuración sobrescrita, variables CSS en conflicto, convivencia con otras bibliotecas de UI
- Componentes que no renderizan: rutas
contentincorrectas, problemas conglobals.css, sensibilidad a mayúsculas en importaciones - Errores de TypeScript: tipos de
variantfaltantes, incompatibilidad de React, dependencias de tipos ausentes
Ante un problema, sigue este orden:
- Revisa la configuración (
tailwind.config.js,globals.css) - Revisa las rutas (
content, importaciones) - Revisa las definiciones de tipos (componentes, versiones de dependencias)
Si empiezas con shadcn/ui, prueba todo el flujo en un proyecto vacío. Cuando conozcas la configuración y estos fallos típicos, úsalo en un proyecto real.
shadcn/ui es muy útil, pero la configuración tiene su complejidad. Con estos métodos de diagnóstico, los problemas dejan de ser un susto.
FAQ
¿Por qué pierdo todos los estilos después de instalar shadcn/ui?
• Si el array plugins de tailwind.config.js está completo
• Si la ruta de globals.css es correcta
• Si todas las variables CSS están definidas
Solución: respalda la configuración antes de instalar, compara las diferencias después y restaura manualmente lo que falte.
¿Por qué los estilos de los componentes fallan al cambiar al modo oscuro?
• La clase .dark debe existir
• Todas las variables del tema deben redefinirse
• En Tailwind v4 hace falta mapear las variables con @theme inline
¿Puede shadcn/ui convivir con MUI?
• Establece prefix: 'tw-' para prefijar todas las clases de Tailwind
• Usa shadcn/ui en componentes nuevos y conserva MUI en los antiguos
• Migra de forma gradual, no cambies todo de golpe
No se recomienda desactivar Preflight, porque afecta a los estilos de Tailwind.
¿Qué hago si la prop variant de Button da error de TypeScript?
• VariantProps<typeof buttonVariants> debe heredarse
• Asegúrate de que el archivo del componente exporta los tipos completos
• Instala @types/react y @types/react-dom
Si faltan tipos, vuelve a ejecutar npx shadcn@latest add button para instalar el componente.
¿Se puede usar shadcn/ui con React 19?
• Al instalar, usa --legacy-peer-deps o --force
• O especifica la versión de react-is en overrides de package.json
• En proyectos nuevos, React 18 es más estable hasta que las dependencias se actualicen
¿Por qué el componente funciona en local pero en producción falla al no encontrar el módulo?
• Los archivos de componentes shadcn/ui están en minúsculas (button.tsx)
• La ruta de importación debe coincidir (@/components/ui/button)
• Windows no distingue mayúsculas; Linux/Mac sí: en local puede pasar y en producción fallar
Revisa todas las importaciones y asegúrate de que las rutas coincidan exactamente.
10 min de lectura · Publicado el: 2 abr 2026 · Actualizado el: 21 ago 2026
Tailwind y shadcn/ui en práctica
Si llegaste desde búsqueda, lo más rápido es ir al artículo anterior o siguiente de esta misma serie.
Anterior
React Compiler + shadcn/ui: desarrollo frontend en la era de la optimización automática
Guía práctica de React Compiler en proyectos shadcn/ui: cómo activarlo, lecciones reales, puntos clave de migración y comparativa de rendimiento para pasar de la optimización manual a la automática
Parte 13 de 14
Siguiente
Este es el artículo más reciente de la serie por ahora.



Comentarios
Inicia sesión con GitHub para dejar un comentario