How to fix Tailwind CSS custom colors not showing in production

I defined custom colors in my tailwind.config.js (or @theme in Tailwind v4) and they work perfectly in development, but the classes disappear in the production build:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: '#6366f1',
      },
    },
  },
}
// Component
const color = 'brand'
return <div className={`text-${color}-500`}>Hello</div> // disappears in prod

Why does this happen and how do I fix it?

Solution

Tailwind scans your source files for class names at build time and removes any class it did not find. It does a static string search, not a JavaScript evaluation. If you build a class name dynamically by concatenating strings, Tailwind never sees the full class name and purges it.

The fix is to always use complete, static class name strings:

// Broken: Tailwind only sees "text-" and "brand" separately
const color = 'brand'
return <div className={`text-${color}-500`}>Hello</div>

// Fixed: Tailwind sees the full class name "text-brand-500"
const colorClass = 'text-brand-500'
return <div className={colorClass}>Hello</div>

If you need to switch between classes based on a prop, use a lookup object instead of concatenation:

const colorMap = {
  brand: 'text-brand-500',
  danger: 'text-red-500',
  success: 'text-green-500',
}

function Badge({ color }: { color: keyof typeof colorMap }) {
  return <span className={colorMap[color]}>Badge</span>
}
Alternative #1

If you genuinely need to generate class names dynamically (for example, from CMS data or user input), add those classes to the safelist in tailwind.config.js. Safelisted classes are always included in the build regardless of whether Tailwind detects them in source files:

// tailwind.config.js
module.exports = {
  safelist: [
    'text-brand-500',
    'bg-brand-100',
    // Use a pattern to safelist a whole group of classes:
    {
      pattern: /bg-(red|green|blue)-(100|500|900)/,
    },
  ],
}

Keep the safelist small and specific. Safelisting broad patterns like /bg-.*/ defeats the purpose of purging and inflates your CSS bundle.

Alternative #2

In Tailwind v4, custom colors are defined in CSS using the @theme directive rather than in a JavaScript config file. The same rule about static class names applies, but the definition syntax is different:

/* globals.css */
@import "tailwindcss";

@theme {
  --color-brand: #6366f1;
  --color-brand-light: #a5b4fc;
}

These tokens generate utilities like text-brand, bg-brand, and border-brand-light. Write the full class name statically in your components for Tailwind to detect them at build time.

Last modified: April 16, 2026
Stay in the loop
Subscribe to our newsletter to get the latest articles delivered to your inbox