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.
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.
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-cssis deprecated. Its npm page states: "This project is no longer maintained. Please use PurgeCSS instead." Do not usepurify-cssin new projects.
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.
You’re supporting older browsers and writing modern CSS (e.g., gap, aspect-ratio).
autoprefixer (as a PostCSS plugin).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).
Your production bundle includes verbose, unoptimized CSS.
cssnano (as a PostCSS plugin).// 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.
You’re using Bootstrap or Tailwind and shipping 500KB of CSS but only using 10%.
purify-css) via @fullhuman/postcss-purgecss.// postcss.config.js
plugins: [
require('@fullhuman/postcss-purgecss')({
content: ['./src/**/*.{js,jsx,ts,tsx,html}'],
defaultExtractor: content => content.match(/[^\s"'`;{}]+/g) || []
})
]
You need fine control over transforms (e.g., custom property fallbacks, RTL support).
postcss and add plugins as needed.postcss-custom-properties, postcss-rtl, etc.const processor = postcss([
require('postcss-custom-properties'),
require('autoprefixer'),
require('cssnano')
]);
cssnano removes unused CSS”No. cssnano only optimizes used CSS (e.g., #ff0000 → red). It does not analyze your app to remove .btn-primary if you never use it. For that, you need tree-shaking tools like PurgeCSS.
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.
purify-css in 2024As 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.
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
]
| Package | Type | Primary Job | Works With PostCSS? |
|---|---|---|---|
postcss | CSS Processor | Runs plugins to transform CSS | N/A (it is the host) |
autoprefixer | PostCSS Plugin | Adds vendor prefixes | ✅ Yes |
cssnano | PostCSS Plugin | Minifies and optimizes CSS | ✅ Yes |
purify-css | Standalone Tool | Removes unused CSS (⚠️ deprecated) | ❌ No |
postcss as your foundation if you need modern CSS processing.autoprefixer if you support browsers that need prefixes (check caniuse.com).cssnano in production builds to reduce file size.purify-css with PurgeCSS (via @fullhuman/postcss-purgecss) for dead code elimination.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.
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.
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.
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.
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.
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.
Read full docs here.