Problem
After upgrading from Tailwind v3 to v4, the build fails with:
CssSyntaxError: tailwindcss: /app/globals.css:1:1: Cannot apply unknown utility
class `border-border`. Are you using CSS modules or similar and missing
`@reference`? https://tailwindcss.com/docs/functions-and-directives#reference-directive
This happens in CSS modules (.module.css) or separate CSS files that use @apply but do not directly import Tailwind's base styles:
/* components/card.module.css -- breaks in Tailwind v4 */
.card {
@apply border-border bg-background text-foreground rounded-lg p-4;
}
Solution
Option 1: Reference your globals.css (recommended when using custom theme tokens)
/* components/card.module.css */
@reference "../app/globals.css";
.card {
@apply border-border bg-background text-foreground rounded-lg p-4;
}
Use this when your globals.css defines custom theme tokens via CSS variables (e.g., border-border, bg-background from shadcn/ui).
Option 2: Reference Tailwind directly (when using only default utilities)
/* components/card.module.css */
@reference "tailwindcss";
.card {
@apply rounded-lg p-4 text-gray-900 border border-gray-200;
}
Use this when you only need Tailwind's built-in utility classes.
Why It Works
Tailwind v4 moved from a JavaScript config file (tailwind.config.ts) to a CSS-first configuration model. In v3, the PostCSS plugin resolved all utility classes globally across the project. In v4, each CSS file is processed more independently and needs to know where to find utility definitions.
The @reference directive tells the Tailwind compiler where to find utility and theme definitions without emitting those styles into the current file. Unlike @import (which would duplicate the base styles into every CSS module), @reference is compile-time only -- it resolves utility classes during the build but produces no additional CSS output.
Context
- Tailwind CSS v4.0+ (breaking change from v3)
- Affects CSS modules (
.module.css), co-located CSS files, and any file using@applythat is not the main CSS entry point - The official migration tool (
npx @tailwindcss/upgrade) may not catch all instances, especially in CSS modules - If using shadcn/ui or similar libraries with CSS variable tokens, you must reference the file that defines those variables
- The
@referencepath is relative to the file containing it