Buenas prácticas con Tailwind CSS en proyectos grandes

A laptop screen showing a code editor with visible programming code in a dimly lit environment.
Foto de Daniil Komov en Pexels

Estructura de carpetas y separación de responsabilidades

En un proyecto con varios módulos y componentes, la forma en que organizamos los archivos determina cuánto tiempo perdemos buscando clases o estilos. Una convención que funciona bien es crear una carpeta ui para componentes reutilizables y otra pages para vistas completas. Dentro de ui podemos agrupar por dominio (ui/buttons, ui/forms, ui/cards) y colocar los archivos .tsx o .vue junto a sus estilos Tailwind en el mismo directorio. Así, al abrir un componente, vemos de inmediato qué clases se aplican.

Configura correctamente el purge/content

Tailwind genera cientos de clases; sin una configuración adecuada el bundle puede inflar hasta varios megabytes. En proyectos grandes, el apartado content (antes purge) debe incluir todos los puntos de entrada donde aparecen clases, incluso los archivos de pruebas o storybooks. Un ejemplo típico en tailwind.config.js sería:

module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./public/**/*.html",
"./stories/**/*.{js,ts,jsx,tsx}"
],
theme: {
extend: {}
},
plugins: []
};

Al mantener la lista actualizada evitamos que clases usadas dinámicamente se eliminen en la fase de producción.

Uso prudente de @apply y componentes reutilizables

El poder de @apply reside en extraer combinaciones de utilidades que aparecen en varios lugares. Sin embargo, abusar de él crea capas de CSS que vuelven a ser difíciles de rastrear. Una buena práctica es limitar su uso a patrones de diseño estables, como botones primarios, tarjetas o formularios. Por ejemplo:

.btn-primary {
@apply bg-blue-600 text-white font-medium py-2 px-4 rounded hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-300;
}

De esta forma, en el HTML solo usamos class="btn-primary" y mantenemos la consistencia visual.

Nomenclatura y prefijos para evitar colisiones

En equipos grandes, varios desarrolladores pueden crear componentes con nombres similares. Añadir un prefijo al proyecto (tw- por ejemplo) a clases personalizadas o a componentes ayuda a distinguirlas de las utilidades nativas. Además, si usamos plugins externos que añaden sus propias clases, el prefijo evita sobrescribir estilos sin darnos cuenta.

  • Ejemplo de clase prefijada: class="tw-card"
  • En el CSS: .tw-card { @apply bg-white shadow-md rounded-lg p-6; }

Gestión de temas y modo oscuro

Tailwind incluye soporte nativo para dark y media. En una base de código grande conviene centralizar la lógica del tema en el archivo de configuración, definiendo colores personalizados dentro de theme.extend.colors. Así, cualquier componente que necesite adaptarse al modo oscuro simplemente usa la variante dark: sin duplicar valores.

module.exports = {
darkMode: "class", // o "media"
theme: {
extend: {
colors: {
primary: {
light: "#3b82f6",
dark: "#1e40af"
}
}
}
}
};

Con esto, un botón se escribe class="bg-primary-light dark:bg-primary-dark" y el cambio de tema se controla con una única clase en el html o body.

Limita la profundidad de variantes y evita combinaciones excesivas

Tailwind permite encadenar variantes como sm:hover:bg-red-500. En equipos grandes, la práctica de combinar más de tres variantes suele generar clases muy específicas y difíciles de mantener. Establece una regla interna: máximo dos variantes por clase y usa componentes o @apply para casos más complejos. Esto reduce la explosión de clases y facilita la auditoría con herramientas como tailwindcss-cli o purgecss.

Integración de linting y pruebas visuales

Al igual que con JavaScript, el CSS también se beneficia de un linting automático. Configura stylelint con el plugin stylelint-config-tailwindcss para detectar clases no válidas o uso de @apply incorrecto. Además, incorpora pruebas visuales (por ejemplo, con Chromatic o Storybook) para garantizar que los cambios en la configuración de Tailwind no rompen la UI en producción.

Aplicando estas buenas prácticas, tu equipo podrá escalar Tailwind CSS sin perder la velocidad de desarrollo ni la claridad del código, manteniendo una base de estilos coherente y fácil de mantener a lo largo del tiempo.