Skip to content

Safelisting in TailwindCSS v4

The safelisting feature in TailwindCSS ensures critical utility classes are included in your final CSS bundle even if they aren't directly referenced in your markup. Here's how the safelist approach evolved in Tailwind v4.

Problem Statement

In TailwindCSS v3, you could safely include classes using JS configuration:

js
// tailwind.config.js (v3)
export default {
  safelist: [
    {
      pattern: /grid-cols-+/,
      variants: ["sm", "md", "lg", "xl"],
    },
  ],
}

However, TailwindCSS v4 removed the JS-based safelist property. Attempting to use it results in errors since Tailwind now favors CSS-first configuration. Without safelisting, developers had to implement workarounds like:

  • Creating dummy elements with needed classes
  • Using @apply in CSS files to force inclusion
  • Adding unused class names to markup

Solution: @source inline() Directive (v4.1+)

Tailwind 4.1 introduced the @source inline() directive as a safe-list replacement. Paste this in your CSS file where Tailwind is imported:

css
@import "tailwindcss";

@source inline('{sm:,md:,lg:,xl:,}grid-cols-{{1..12}}');

Key Syntax Features

  1. Variants Prefix variants followed by comma for base + variants:
    {sm:,} generates:

    • grid-cols-* (base)
    • sm:grid-cols-*
  2. Numerical ranges with {{start..end}}:
    grid-cols-{{1..12}} generates classes from grid-cols-1 to grid-cols-12

  3. Multiple values/patterns Comma-separate lists:
    p{,,x,y,t,b,l,r}-{1..10}

WARNING

Always include a trailing comma after variants to generate base classes. This:
{sm:,} includes both base and sm variants.
Whereas {sm:} would generate only sm variants.

Advanced Examples

  1. Multiple variants with dynamic values:
css
@source inline('{hover:,focus:}bg-blue-{50,100,200,400,800}');
  1. Complex ranges with explicit values:
css
@source inline('{md:,lg:}w-{1/2,1/3,full,{300..600..50}}');
  1. Combined utilities:
css
@source inline('{m,p}{t,b}-{0,4,8,12}');

Performance Consideration

Excessive safe-listing significantly increases CSS bundle size. Only include essential classes. Test your compiled CSS with Tailwind Playground to verify output.

Pre-v4.1 Workarounds

Versions ≤4.0.17 don't support safe-listing. If upgrading isn't possible:

Option 1: Generate classes via external file

js
// generate-classes.js
const fs = require('fs');
const classes = [
  'sm:grid-cols-1', 'sm:grid-cols-2', /* ... */, 'xl:grid-cols-12'
];
fs.writeFileSync('safelist.txt', classes.join('\n'));
css
@import "tailwindcss";
@source "safelist.txt";

Option 2: Force inclusion via theme config (limited)

css
@import "tailwindcss";
@theme static {
  --grid-columns: 12; /* Only affects CSS variables */
}

When to Use Safelisting

Common valid use cases include:

  • Dynamic classes from CMS/user-generated content
  • Third-party component libraries
  • Programmatically generated class names
  • Responsive utilities not detectable in static code

TIP

For static sites, prefer Tailwind's static analysis over manual safe-listing. Run npx tailwindcss --watch with your content files configured.

Additional Resources

The @source inline() directive provides a powerful, CSS-native solution for safe-listing in Tailwind v4.1+. Use it judiciously to optimize your workflow without compromising performance.