postcss vs autoprefixer vs cssnano vs purify-css
CSS Optimization and Processing Tools
postcssautoprefixercssnanopurify-cssSimilar Packages:
CSS Optimization and Processing Tools

postcss is a tool for transforming CSS with JavaScript plugins. autoprefixer and cssnano are popular PostCSS plugins that add vendor prefixes and minify CSS, respectively. purify-css is a standalone tool for removing unused CSS selectors, but it is officially deprecated and should not be used in new projects. These packages often work together in modern frontend build pipelines to optimize CSS for production.

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
postcss60,326,81028,929204 kB287 months agoMIT
autoprefixer18,451,53822,613199 kB4122 days agoMIT
cssnano6,573,5204,9557.37 kB1022 months agoMIT
purify-css10,8179,896-829 years agoMIT

CSS Optimization and Processing: autoprefixer, cssnano, postcss, and purify-css Compared

When building modern web applications, managing CSS efficiently is critical for performance, maintainability, and browser compatibility. The packages autoprefixer, cssnano, postcss, and purify-css each play a role in this ecosystem — but they serve very different purposes and often work together rather than compete directly. Let’s clarify what each does, how they fit into your build pipeline, and where you might run into pitfalls.

🧩 Core Roles: Processor vs Plugins vs Standalone Tools

postcss is not a CSS optimizer or prefixer by itself — it’s a tool for transforming CSS with JavaScript plugins. Think of it as the engine that powers many modern CSS workflows.

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer'),
    require('cssnano')
  ]
};

autoprefixer is a PostCSS plugin that automatically adds vendor prefixes (like -webkit-, -moz-) based on your target browsers.

// Input CSS
const input = 'display: grid;';

// After autoprefixer (with older browser targets)
// Output: display: -ms-grid; display: grid;

cssnano is also a PostCSS plugin that minifies and optimizes CSS by removing redundant code, shortening values, and applying safe transformations.

// Input
const input = '.foo { color: #ff0000; padding: 10px 10px 10px 10px; }';

// After cssnano
// Output: .foo{color:red;padding:10px}

purify-css, however, is a standalone tool (not a PostCSS plugin) that removes unused CSS selectors by analyzing your HTML and JavaScript files to see which classes are actually used.

// CSS
const css = '.used { color: red; } .unused { display: none; }';

// JS/HTML content
const content = ['<div class="used"></div>'];

// After purify-css
// Output: .used { color: red; }

⚠️ Important: As of 2023, purify-css is deprecated. Its npm page states: "This project is no longer maintained. Please use PurgeCSS instead." Do not use purify-css in new projects.

🔌 Integration Patterns: How They Work Together

In practice, postcss acts as the host, while autoprefixer and cssnano plug into it. A typical production build might look like this:

// Using PostCSS programmatically
const postcss = require('postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

const result = await postcss([
  autoprefixer({ browsers: ['> 1%', 'last 2 versions'] }),
  cssnano({ preset: 'default' })
]).process(cssString, { from: undefined });

console.log(result.css); // Prefixed + minified CSS

You’d typically run this after your Sass/Less/CSS-in-JS compilation step and before bundling.

In contrast, purify-css (or its successor PurgeCSS) runs separately, usually as a final pass to strip unused rules:

// ❌ Do not use purify-css in new code
// Instead, use PurgeCSS with PostCSS via postcss-purgecss
const purgecss = require('@fullhuman/postcss-purgecss');

module.exports = {
  plugins: [
    purgecss({
      content: ['./src/**/*.html', './src/**/*.js']
    }),
    autoprefixer(),
    cssnano()
  ]
};

Note: Order matters in PostCSS. You generally want to remove unused CSS before minifying, so PurgeCSS (or similar) should come before cssnano.

🎯 When to Use What: Real Build Scenarios

Scenario 1: You Need Cross-Browser Compatibility

You’re supporting older browsers and writing modern CSS (e.g., gap, aspect-ratio).

  • Use autoprefixer (as a PostCSS plugin).
  • It reads your browserslist config and adds only the necessary prefixes.
// package.json
"browserslist": ["> 1%", "last 2 versions"]

Without this, your layout might break in Safari 14 or IE11 (if targeted).

Scenario 2: You Want Smaller CSS Files

Your production bundle includes verbose, unoptimized CSS.

  • Use cssnano (as a PostCSS plugin).
  • It safely compresses your CSS without changing behavior.
// Enables aggressive but safe optimizations
const result = await postcss([cssnano({ preset: 'advanced' })]).process(css);

Avoid running cssnano in development — it slows down rebuilds and makes debugging harder.

Scenario 3: Your App Has a Lot of Unused UI Library CSS

You’re using Bootstrap or Tailwind and shipping 500KB of CSS but only using 10%.

  • Use PurgeCSS (not purify-css) via @fullhuman/postcss-purgecss.
  • Analyzes your templates to keep only referenced classes.
// postcss.config.js
plugins: [
  require('@fullhuman/postcss-purgecss')({
    content: ['./src/**/*.{js,jsx,ts,tsx,html}'],
    defaultExtractor: content => content.match(/[^\s"'`;{}]+/g) || []
  })
]

Scenario 4: You’re Building a Custom CSS Toolchain

You need fine control over transforms (e.g., custom property fallbacks, RTL support).

  • Start with postcss and add plugins as needed.
  • The ecosystem has plugins for almost everything: postcss-custom-properties, postcss-rtl, etc.
const processor = postcss([
  require('postcss-custom-properties'),
  require('autoprefixer'),
  require('cssnano')
]);

⚠️ Common Misconceptions and Pitfalls

Myth: “cssnano removes unused CSS”

No. cssnano only optimizes used CSS (e.g., #ff0000red). It does not analyze your app to remove .btn-primary if you never use it. For that, you need tree-shaking tools like PurgeCSS.

Myth: “autoprefixer makes my CSS work everywhere”

It only handles prefixing, not feature polyfills. If you use grid and target IE10, you still need a polyfill — autoprefixer alone won’t help.

Pitfall: Running purify-css in 2024

As noted, purify-css is deprecated and unmaintained. It hasn’t kept up with modern JavaScript frameworks (React, Vue SFCs), leading to false positives/negatives. Migrate to PurgeCSS.

Pitfall: Wrong Plugin Order in PostCSS

If you minify before purging, cssnano might rename or restructure selectors in ways that confuse PurgeCSS. Always purge first, then minify.

// ✅ Correct order
plugins: [
  purgecssPlugin,
  autoprefixer,
  cssnano
]

📊 Summary: Responsibilities at a Glance

PackageTypePrimary JobWorks With PostCSS?
postcssCSS ProcessorRuns plugins to transform CSSN/A (it is the host)
autoprefixerPostCSS PluginAdds vendor prefixes✅ Yes
cssnanoPostCSS PluginMinifies and optimizes CSS✅ Yes
purify-cssStandalone ToolRemoves unused CSS (⚠️ deprecated)❌ No

💡 Final Recommendations

  • Always use postcss as your foundation if you need modern CSS processing.
  • Add autoprefixer if you support browsers that need prefixes (check caniuse.com).
  • Add cssnano in production builds to reduce file size.
  • Replace purify-css with PurgeCSS (via @fullhuman/postcss-purgecss) for dead code elimination.
  • Never use purify-css in new projects — it’s outdated and unsupported.

These tools are complementary, not competitors. Used together correctly, they form a robust pipeline for delivering lean, compatible, and maintainable CSS.

How to Choose: postcss vs autoprefixer vs cssnano vs purify-css
  • postcss:

    Choose postcss as the foundation for any advanced CSS processing workflow. It doesn't do anything by itself but provides a plugin architecture that enables transformations like autoprefixing, minification, custom property handling, and more. If you need fine-grained control over your CSS pipeline or want to leverage modern CSS features with fallbacks, PostCSS is the standard choice in the JavaScript ecosystem.

  • autoprefixer:

    Choose autoprefixer when you need to automatically add vendor prefixes to your CSS based on browser support requirements. It integrates seamlessly as a PostCSS plugin and uses your project's browserslist configuration to determine which prefixes are necessary. This is essential for ensuring consistent rendering across older browsers without manually maintaining prefix rules.

  • cssnano:

    Choose cssnano when you need to minify and optimize your CSS for production. It works as a PostCSS plugin and safely reduces file size by removing redundant code, shortening values, and applying other optimizations. Use it in your production build pipeline after other transformations like prefixing, but avoid using it during development as it hinders debugging.

  • purify-css:

    Do not choose purify-css for new projects — it is officially deprecated according to its npm page and repository. Instead, use PurgeCSS (typically via the @fullhuman/postcss-purgecss PostCSS plugin) to remove unused CSS selectors by analyzing your HTML and JavaScript files. PurgeCSS is actively maintained, supports modern frameworks, and integrates cleanly into PostCSS-based build processes.

README for postcss

PostCSS

Philosopher’s stone, logo of PostCSS

PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba, and JetBrains. The Autoprefixer and Stylelint PostCSS plugins are some of the most popular CSS tools.


  Built by Evil Martians, go-to agency for developer tools.


Docs

Read full docs here.