purgecss, tailwindcss, unocss, and windicss are tools used in modern frontend workflows to manage CSS efficiently. purgecss is a standalone utility that removes unused CSS from stylesheets by analyzing your content files. tailwindcss is a highly configurable utility-first CSS framework that includes built-in tree-shaking via its JIT (Just-in-Time) compiler. unocss is an atomic CSS engine that generates styles on demand with high performance and extensibility through presets. windicss was a drop-in replacement for Tailwind CSS that offered faster builds and additional features, but it has been officially deprecated and is no longer maintained.
When building modern web applications, managing CSS bloat is critical for performance. The tools purgecss, tailwindcss, unocss, and windicss address this problem in different ways — from post-processing cleanup to on-demand generation. Let’s compare their approaches, capabilities, and trade-offs.
purgecss assumes you already have a full CSS file and removes what isn’t used.
// purgecss.config.js
module.exports = {
content: ['./src/**/*.{html,js,jsx}'],
css: ['./public/css/*.css'],
defaultExtractor: content => content.match(/[^\s"'`;{}]+/g) || []
};
tailwindcss, unocss, and windicss generate only the CSS you use.
⚠️ Note:
windicssis deprecated as of 2023. The official GitHub repository states: “Windi CSS is no longer maintained. We recommend migrating to Tailwind CSS v3+ or UnoCSS.” Do not use it in new projects.
tailwindcss uses a Just-in-Time (JIT) compiler.
purgecss — unused classes are never generated.// tailwind.config.js
module.exports = {
content: ["./src/**/*.{html,js}"],
theme: { extend: {} },
plugins: []
};
unocss uses a transformer-based architecture.
// uno.config.ts
import { defineConfig } from 'unocss';
export default defineConfig({
presets: [
// Built-in preset similar to Tailwind
require('@unocss/preset-uno').default()
]
});
windicss (deprecated) used a virtual module system.
// windi.config.js (no longer recommended)
export default {
extract: { include: ['src/**/*.{vue,html,js}'] }
};
All three active tools support arbitrary values (e.g., top-[123px]), but differ in extension models.
tailwindcss uses plugins and theme extensions.
theme.extend.// Add a custom utility in tailwind.config.js
plugin(function({ addUtilities }) {
addUtilities({
'.text-gradient': {
backgroundClip: 'text',
color: 'transparent'
}
});
})
unocss uses rules and presets.
@unocss/preset-uno mimics Tailwind + Windi).// Custom rule in uno.config.ts
rules: [
[/^text-gradient$/, { 'background-clip': 'text', color: 'transparent' }]
]
purgecss doesn’t generate CSS, so it has no syntax — only configuration for extraction.
// Safelist specific classes that aren’t detected statically
safelist: ['bg-red-500', /^swiper-/]
tailwindcss has first-party integrations with major frameworks:
@tailwindcss/forms, typography, etc.).unocss offers universal framework support:
purgecss is build-tool agnostic:
windicss had strong Vue and Vite integration, but those communities have largely migrated to UnoCSS or Tailwind.
You’re using dynamic class binding: <div class="text-${color}-500">.
purgecss will miss these unless you configure a custom extractor or safelist.
defaultExtractor: content => [...content.matchAll(/text-(\w+)-500/g)].map(m => `text-${m[1]}-500`)
tailwindcss handles this automatically in JIT mode — no config needed.
unocss also handles it natively — its transformer sees the literal string during build.
windicss handled it well, but again — don’t use it.
You want to add a new spacing scale: space-4.5 → 18px.
tailwindcss: Extend theme.
theme: { extend: { spacing: { '4.5': '18px' } } }
unocss: Add a rule or extend preset theme.
theme: { spacing: { '4.5': '18px' } }
purgecss: Not applicable — you’d add it to your CSS manually, then hope it’s not purged.
| Feature | purgecss | tailwindcss | unocss | windicss |
|---|---|---|---|---|
| Status | ✅ Active | ✅ Active | ✅ Active | ❌ Deprecated |
| Approach | Remove unused CSS | Generate on-demand | Generate on-demand | Generate on-demand |
| File Scanning | Required | Required (for content) | Not required | Required |
| Arbitrary Values | ❌ (relies on source) | ✅ | ✅ | ✅ |
| Custom Rules | ❌ | ✅ (via plugins) | ✅ (regex rules) | ✅ |
| Framework Support | Universal | First-party integrations | Universal | Strong in Vue/Vite |
| Best For | Legacy CSS cleanup | Stable, team-friendly | High perf, customization | Avoid in new projects |
tailwindcss.unocss.purgecss remains a solid choice for reducing bundle size.windicss — it’s deprecated, and better alternatives exist.All three active tools solve real problems, but they operate at different layers of the CSS pipeline. Choose based on whether you need to clean existing CSS (purgecss) or generate minimal CSS from scratch (tailwindcss or unocss).
Choose tailwindcss if you want a mature, well-documented utility-first framework with strong community support, first-party integrations (like with Next.js), and a robust plugin ecosystem. Its JIT engine provides fast builds and accurate purging without extra configuration. Ideal for teams prioritizing stability, accessibility, and long-term maintainability.
Choose purgecss if you're working with a traditional CSS codebase or a non-utility framework and need a reliable, standalone tool to eliminate unused styles. It integrates well with build systems like Webpack or Vite and gives you fine-grained control over safelisting and extraction logic. However, it requires manual configuration and doesn't generate CSS — only trims it.
Choose unocss if you need maximum build performance, flexibility in syntax, or the ability to define custom atomic rules via presets. It supports on-demand generation, arbitrary values, and variants out of the box, and works across frameworks without relying on file scanning. Best for advanced teams comfortable with configuration and seeking cutting-edge optimization.
Do not choose windicss for new projects. The project was officially deprecated in 2023, with maintainers recommending migration to tailwindcss or unocss. While it once offered faster builds and extra features like implicit class sorting, it is no longer updated and may contain unpatched bugs or compatibility issues.
A utility-first CSS framework for rapidly building custom user interfaces.
For full documentation, visit tailwindcss.com.
For help, discussion about best practices, or feature ideas:
Discuss Tailwind CSS on GitHub
If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.