Postcss-loader: Using PostCSS with webpack

postcss-loader runs PostCSS inside webpack. This guide covers installation, the correct loader order, options and the errors people hit most often.

Illustrated cover: Postcss-loader: Using PostCSS with webpack
Illustration by the editorial team.

What postcss-loader is

postcss-loader is the official webpack loader for PostCSS, maintained in the webpack-contrib organisation. It passes each CSS file through your PostCSS plugins before other loaders handle it. At the time of checking, the current version is 8.2.1.

From the postcss-loader 8.2.1 package and README.
RequirementValue
webpackv5 (use postcss-loader v4 for webpack 4)
Node.js18.12.0 or newer
PostCSS peer^7.0.0 || ^8.0.1
RspackSupported as an optional peer

Install

Terminal
npm install --save-dev postcss-loader postcss css-loader style-loader autoprefixer

Install postcss yourself; the loader declares it as a peer dependency and uses your copy.

Basic webpack configuration

webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      }
    ]
  }
}

Then add a postcss.config.js in the project root. postcss-loader finds it automatically.

Loader order matters

webpack applies loaders from right to left (bottom to top). In the array above:

  1. postcss-loader runs first and transforms the CSS.
  2. css-loader resolves @import and url().
  3. style-loader injects the result into the page (or use mini-css-extract-plugin to output files).

With Sass, put sass-loader to the right of postcss-loader so Sass compiles first:

webpack.config.js
{
  test: /\.s[ac]ss$/i,
  use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
}

Inline options with postcssOptions

If you prefer not to use a separate config file, pass options inline:

webpack.config.js
{
  loader: 'postcss-loader',
  options: {
    postcssOptions: {
      plugins: [['autoprefixer', {}]]
    }
  }
}

The README documents these main options:

  • postcssOptions: plugins, parser, syntax and other PostCSS options; can be an object or a function.
  • postcssOptions.config: a path to a specific config file, or false to ignore config files.
  • execute: run PostCSS-JS (CSS-in-JS) sources.
  • sourceMap: enable or disable source maps.
  • implementation: choose a specific PostCSS package or version.

CSS Modules

Enable CSS Modules on css-loader; postcss-loader stays the same. Give css-loader importLoaders: 1 so imported files also pass through PostCSS:

webpack.config.js
{
  test: /\.css$/i,
  use: [
    'style-loader',
    { loader: 'css-loader', options: { modules: true, importLoaders: 1 } },
    'postcss-loader'
  ]
}

Extracting CSS for production

For production, replace style-loader with mini-css-extract-plugin so CSS is emitted as files. Add cssnano in your PostCSS config, or use css-minimizer-webpack-plugin, to minify.

Common errors

“PostCSS plugin … requires PostCSS 8”

You are running an old postcss-loader that bundles PostCSS 7. Upgrade postcss-loader and install postcss 8 directly.

“Cannot find module 'postcss'”

The peer dependency is missing. Run npm install --save-dev postcss.

Config is not applied

Check the file name and that postcssOptions.config is not set to false. ESM/CommonJS mismatches are a common cause; see the config guide.

Node.js version error on install

postcss-loader 8 needs Node.js 18.12+. Upgrade Node.js to a current LTS release.

Do you need postcss-loader at all?

Only with webpack or Rspack. Vite applies PostCSS automatically, and Parcel has built-in support too. If you are starting a new project, the bundler you choose decides whether this loader is needed. The compatibility table on the home page summarises the options.

Get PostCSS 8.5.32

Free, MIT licensed, downloaded from the official GitHub repository.

Download PostCSS