Optimize Tailwind CSS Production Build: 7 Steps

published on 05 October 2024

Want a faster website with Tailwind CSS? Here's how to shrink your CSS file from 3645.2kB to under 10kB:

  1. Use PurgeCSS
  2. Reduce color options
  3. Remove extra breakpoints
  4. Turn off unused features
  5. Use Just-in-Time mode
  6. Improve PostCSS setup
  7. Shrink and compress CSS

These steps can slash your CSS file size by over 99%. Netflix's Top 10 site? Just 6.5kB of CSS.

Here's a quick comparison of Tailwind CSS file sizes:

Build Type Uncompressed Minified & Gzipped Brotli Compressed
Development 3645.2kB 294.2kB 72.8kB
Optimized Production < 10kB < 10kB < 10kB

Ready to speed up your site? Let's dive in.

1. Use PurgeCSS

PurgeCSS

PurgeCSS is a tool that can slash your Tailwind CSS file size. It does this by cutting out unused CSS classes from your final build.

Check out these numbers:

Tailwind CSS Build Uncompressed Minified Gzip Brotli
Default 3645.2kB 2936.0kB 294.2kB 72.8kB
With PurgeCSS < 10kB < 10kB < 10kB < 10kB

That's right - PurgeCSS can shrink your CSS file by over 99%!

Setting Up PurgeCSS

Here's how to add PurgeCSS to your Tailwind project:

  1. Install it:
npm install @fullhuman/postcss-purgecss --save-dev
  1. Update postcss.config.js:
const purgecss = require('@fullhuman/postcss-purgecss')
const cssnano = require('cssnano')

module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
    cssnano({ preset: 'default' }),
    purgecss({
      content: ['./layouts/**/*.html', './src/**/*.vue', './src/**/*.jsx'],
      defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
    })
  ]
}
  1. For development, tweak postcss.config.js:
module.exports = {
  plugins: [
    require('tailwindcss'),
    process.env.NODE_ENV === 'production' ? require('autoprefixer') : null,
    process.env.NODE_ENV === 'production'
      ? cssnano({ preset: 'default' })
      : null,
    // PurgeCSS config...
  ]
}

Writing HTML for PurgeCSS

To get the most out of PurgeCSS:

  1. Don't create class strings dynamically. PurgeCSS won't catch them.

  2. Use safelist in your Tailwind config for classes you want to keep:

// tailwind.config.js
module.exports = {
  purge: {
    content: [/* your content paths */],
    safelist: ['bg-red-500', 'text-center']
  },
  // other config...
}
  1. For dynamic content classes, use PurgeCSS ignore comments:
<!-- purgecss start ignore -->
<div class="dynamic-class">
  <!-- Dynamic content here -->
</div>
<!-- purgecss end ignore -->

With PurgeCSS set up right, you can cut your Tailwind CSS file size way down. Netflix's Top 10 site, for example, uses Tailwind and sends just 6.5kB of CSS over the network.

2. Reduce Color Options

Want a smaller CSS file? Cut down on Tailwind colors. Here's how:

Trim Your Palette

Edit tailwind.config.js. Keep only what you need:

// tailwind.config.js
const colors = require('tailwindcss/colors')

module.exports = {
  theme: {
    colors: {
      black: colors.black,
      white: colors.white,
      gray: colors.coolGray,
      blue: colors.blue,
      red: colors.red
    }
  }
}

This cuts out teal, orange, pink, and more. Result? Leaner CSS.

Need custom colors? Add them like this:

module.exports = {
  theme: {
    extend: {
      colors: {
        'brand-blue': '#0077B5',
        'brand-green': '#00A98F'
      }
    }
  }
}

A limited palette keeps things consistent and small.

Pro tip: Use color shades for depth. It's like having more colors without the bloat.

Approach What You Get
Cut unused colors Smaller files, faster loads
Add brand colors Consistent look, focused design
Use color shades Visual depth, no extra colors

Remember: fewer colors = smaller files = faster sites. It's that simple.

3. Remove Extra Breakpoints

Tailwind CSS comes with default breakpoints, but you might not need all of them. Let's trim the fat.

Here's what Tailwind gives you out of the box:

Breakpoint Min-width
sm 640px
md 768px
lg 1024px
xl 1280px
2xl 1536px

But do you really need all five? Probably not.

Streamline Your Breakpoints

1. Check your design

Take a hard look at your design. Most projects work fine with 3-4 breakpoints.

2. Update your config

Open tailwind.config.js and tweak the screens section:

module.exports = {
  theme: {
    screens: {
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
    }
  }
}

This keeps just three breakpoints. Bye-bye, 'xl' and '2xl'.

3. Name them something useful

Why stick with boring 'sm', 'md', 'lg'? Try this:

module.exports = {
  theme: {
    screens: {
      'tablet': '640px',
      'laptop': '1024px',
      'desktop': '1280px',
    }
  }
}

4. Ditch just one breakpoint

Want to keep most but lose '2xl'? Here's how:

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {  
  theme: {    
    screens: Object.fromEntries(      
      Object.entries(defaultTheme.screens).filter(([key, value]) => key !== '2xl')    
    )  
  } 
}

Why bother? Removing just the '2xl' breakpoint can shrink your CSS file by about 20%. That's a big win for such a small change.

4. Turn Off Unused Features

Tailwind CSS is feature-rich, but not every project needs all the bells and whistles. Here's how to slim down your CSS:

Disable Unneeded Plugins

  1. Spot the extras: Look for unused plugins like float, clear, skew, scale, and rotate.

  2. Cut them out: In your tailwind.config.js:

module.exports = {
  // ...
  corePlugins: {
    float: false,
    clear: false,
    skew: false,
    scale: false,
    rotate: false
  }
}

This can make a big difference. Shopify saw a 20% smaller CSS file just by doing this.

Optimize Variants

Variants are great for responsive design, but they can fatten up your CSS. Here's how to keep them in check:

  1. Trim responsive variants:
module.exports = {
  // ...
  variants: {
    appearance: []
  }
}
  1. Use a whitelist: Only include what you need:
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['hover', 'focus'],
      borderColor: ['focus'],
      textColor: ['hover']
    }
  }
}

Smart plugin and variant management can seriously shrink your CSS. Netflix's Top 10 site, built with Tailwind, serves just 6.5kB of CSS. That's tiny!

"Tailwind 3.0+ uses Just-in-Time (JIT) by default—it generates CSS on-the-fly, so no need to purge unused styles for production." - Evil Martians Team

sbb-itb-55aadfa

5. Use Just-in-Time Mode

JIT mode in Tailwind CSS is a game-changer. It creates styles on-the-fly, making your CSS files tiny and your builds lightning-fast.

Why use JIT mode? Here's the scoop:

  • It shrinks CSS by over 95%
  • Large projects compile in ~800ms
  • All variants (like focus-visible) are ready to use
  • Changes in HTML instantly update CSS

How to Turn It On

  1. Check if your build tool supports PostCSS
  2. Update tailwind.config.js:
module.exports = {
  mode: 'jit',
  purge: ['./public/*.html'],
  // other options...
}
  1. Run your build and watch the file size drop

"JIT compiler adds new classes on demand, no recompilation needed." - Tailwind CSS Docs

Heads up: If you're using Tailwind CSS v3.0+, JIT is already on. You're good to go!

6. Improve PostCSS Setup

PostCSS

PostCSS is crucial for optimizing Tailwind CSS. Here's how to set it up:

Create a postcss.config.js file in your project root:

module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
  ],
};

This basic setup uses Tailwind and Autoprefixer. But we can do more for production.

Boost Performance with PostCSS Plugins

Consider these plugins:

  1. postcss-import: Combines CSS files
  2. cssnano: Minifies CSS
  3. purgecss: Removes unused CSS

Here's an enhanced postcss.config.js:

const purgecss = require('@fullhuman/postcss-purgecss')
const cssnano = require('cssnano')

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
    process.env.NODE_ENV === 'production' ? cssnano({ preset: 'default' }) : null,
    process.env.NODE_ENV === 'production' ? purgecss({
      content: ['./layouts/**/*.html', './src/**/*.vue', './src/**/*.jsx'],
      defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
    }) : null
  ]
}

This setup uses cssnano and purgecss only in production.

Install the plugins:

npm install postcss-import cssnano @fullhuman/postcss-purgecss --save-dev

Here's what each plugin does:

Plugin Function Impact
postcss-import Combines CSS files Fewer HTTP requests
cssnano Minifies CSS Smaller file size
purgecss Removes unused CSS Much smaller file size

Tailwind can generate a LOT of CSS. In one case, purgecss reduced 172,000 lines to just 370 - a 99% reduction!

Add this script to your package.json:

"scripts": {
  "build:css": "postcss src/tailwind.css -o static/dist/tailwind.css"
}

Run it with:

npm run build:css

This process creates a lean, production-ready CSS file.

7. Shrink and Compress CSS

Want smaller CSS files? Here's how:

CSSnano: Your CSS Shrink Ray

CSSnano

CSSnano makes CSS tiny. Here's the quick setup:

  1. Install it:
npm install cssnano --save-dev
  1. Add to PostCSS config:
module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
    process.env.NODE_ENV === 'production' && require('cssnano')
  ]
}

Using Tailwind CLI? Just add --minify:

npx tailwindcss -o build.css --minify

Brotli: The CSS Compressor

Brotli

Brotli squeezes CSS even smaller. Look at these numbers:

Method Size
Uncompressed 3645.2kB
Minified 2936.0kB
Gzip 294.2kB
Brotli 72.8kB

Tiny, right?

To use Brotli:

  1. Check if your server supports it
  2. Turn it on in your server settings

Netflix's Top 10 site? Just 6.5kB of CSS. That's minification and compression at work.

Pro tip: Always test compression results. Sometimes, CSSnano might bulk up tiny CSS files.

Wrap-up

Let's recap how to optimize your Tailwind CSS production build:

1. PurgeCSS

This tool is a game-changer. It strips out unused styles, dramatically shrinking your CSS file size. The default Tailwind CSS build is 3645.2kB uncompressed. With PurgeCSS, you can often get it under 10kB compressed.

2. Trim color options

The default Tailwind theme has 84 colors. That's overkill for most projects. Cutting this down can significantly reduce file size.

3. Minimize breakpoints

Each breakpoint duplicates every utility class. Fewer breakpoints = smaller CSS.

4. Disable unused features

Turn off plugins and variants you don't need. Every bit counts!

5. Use Just-in-Time (JIT) mode

This is huge. JIT mode in Tailwind v2.1+ generates styles on-demand. It's lightning-fast, compiling large projects in about 800ms, with incremental rebuilds as quick as 3ms.

6. Optimize PostCSS setup

Use plugins like cssnano to further streamline your CSS.

7. Shrink and compress CSS

Minification and compression are crucial. Check out these numbers:

Method Size
Uncompressed 3645.2kB
Minified 2936.0kB
Gzip 294.2kB
Brotli 72.8kB

That's a massive difference!

For perspective, Netflix's Top 10 site uses just 6.5kB of CSS. That's optimization in action.

Fix Common Problems

Tailwind CSS optimization can be tricky. Here's how to solve some common issues:

Class Purging Issues

Tailwind v3 uses JIT compilation instead of PurgeCSS. This can cause problems:

  • Missing classes from dynamic content
  • Solution: Use safelist in your Tailwind config
module.exports = {
  content: ['./src/**/*.{html,js}'],
  safelist: [
    'prose',
    'prose-sm',
    'prose-lg',
    'prose-xl',
    'prose-2xl',
  ],
  // ...
}

Incorrect Configuration

Setup issues are common, especially with frameworks like Next.js:

Issue Fix
Missing Tailwind directives Add @tailwind directives to main CSS file
Wrong class attribute Use className in JSX
Incorrect paths Check content in tailwind.config.js

Build Errors

1. Package export errors

For Error: Package exports for '...\node_modules\colorette' do not define a valid '.' target:

Check your package.json build command:

{
  "scripts": {
    "build": "tailwindcss build assets/styles.css -o public/styles.css"
  }
}

2. PostCSS transformation errors

For POSTCSS: failed to transform 'css/main.scss' (text/x-scss): TypeError: Object.entries(...).flatMap is not a function:

  • Try different Node.js versions
  • Run postcss-cli separately to isolate the issue

Performance Optimization

For the smallest production build:

  1. Use --minify with Tailwind CLI:
npx tailwindcss -o build.css --minify
  1. Add cssnano to PostCSS plugins:
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
  }
}
  1. Compress CSS with Brotli for better network transfer

FAQs

Does Tailwind purge CSS?

Yes, it does. Tailwind CSS automatically removes unused styles during production builds. This includes styles from base, components, and utilities layers. The result? A much smaller CSS file.

What's Tailwind's build size?

It depends on your setup and how you compress it. Here's a quick look at the default development build sizes:

Build Type Size
Uncompressed 2413.4kB
Minified + Gzip 190.2kB
Brotli 46.2kB

But here's the kicker: these are development sizes. In production, you can shrink it way down.

Take Netflix, for example. They squeezed their Top 10 feature CSS down to just 6.5kB. That's tiny!

Want to slim down your Tailwind CSS? Try these:

  1. Use the --minify flag with Tailwind CLI:
npx tailwindcss -o build.css --minify
  1. Using PostCSS? Add cssnano:
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
  }
}
  1. Compress with Brotli for even smaller file transfers.

Related posts

Read more

Built on Unicorn Platform