@apply: When to Use / Avoid
When to Use
@applycompiles utility classes back into CSS declarations. It has legitimate uses but is widely misused.
Decision
Use @apply when:
- Writing styles for HTML you don't control (third-party widgets, CMS output, markdown)
- Creating base element styles in
@layer basefor consistent prose rendering - The component abstraction is too heavyweight (pure HTML partials, no JS framework)
Avoid @apply when:
- You have framework components available — extract into a component instead
- You're recreating Bootstrap-style component classes (
btn,card) — this fights the utility-first model - Composing complex multi-state styles — you lose the visual clarity of seeing all states in markup
Pattern
/* ✓ Appropriate @apply — styling CMS-generated content */
@layer base {
.cms-content h2 { @apply text-2xl font-bold mt-8 mb-4; }
.cms-content p { @apply text-base leading-relaxed mb-4; }
.cms-content a { @apply text-brand-500 underline hover:text-brand-700; }
}
Common Mistakes
/* ✗ Inappropriate @apply — recreating Bootstrap */
@layer components {
.btn { @apply inline-flex items-center px-4 py-2 rounded-lg font-medium; }
.btn-primary { @apply btn bg-brand-500 text-white hover:bg-brand-600; }
/* Now you have a parallel class system — maintain two things instead of one */
}
In v4 that second rule does not just read badly — it fails the build. @apply accepts utilities only, and a class you defined in @layer components is not one, so @apply btn aborts compilation with Cannot apply unknown utility class btn (verified against tailwindcss 4.2.0). v3 inlined it without complaint (verified against tailwindcss 3.4.19), so this is a breaking change an upgrade surfaces as a build failure. If you need a name you can compose, register it with @utility btn { ... } — @apply btn then resolves. For variant composition, use CVA instead.
See Also
- Component Patterns
- Class Variance Authority
- Reference: https://tailwindcss.com/docs/styling-with-utility-classes#managing-duplication