Safeguard
Open Source

npm autoprefixer: Is It Safe, and How Should You Use It?

The npm autoprefixer package is a PostCSS plugin that adds vendor prefixes to your CSS based on Browserslist data. Here is how it works, why it is a build-time dependency, and how to keep it safe.

Karan Patel
Platform Engineer
5 min read

The npm autoprefixer package is a PostCSS plugin that parses your CSS and adds vendor prefixes automatically, using real-world browser support data from Can I Use via Browserslist. You write plain, standard CSS; autoprefixer figures out which -webkit-, -moz-, and -ms- prefixes the browsers you target still need, and inserts them at build time. It is one of the most-installed packages in the front-end ecosystem, and because it runs during your build rather than shipping to users, its security profile is a little different from a runtime library.

This guide covers what autoprefixer does, how to configure it correctly, and how to think about it as a supply-chain dependency.

What autoprefixer actually does

Autoprefixer solves a problem that used to consume real engineering time: keeping track of which CSS features need vendor prefixes in which browsers. Instead of hand-writing prefixes and manually removing them as browsers dropped the need, you write the unprefixed property and let the plugin do the bookkeeping.

The key insight is that autoprefixer is data-driven. It does not guess. It reads the Can I Use dataset and applies prefixes based on the browsers your project declares as targets. Drop support for an old browser and the corresponding prefixes disappear from your output on the next build.

The current major line is autoprefixer 10.x, and it runs as a PostCSS plugin, so you almost never invoke it directly. It sits in a PostCSS pipeline alongside plugins like postcss-preset-env.

Installing autoprefixer

Install it as a dev dependency, because it only runs during the build:

npm install autoprefixer postcss --save-dev

Then register it in your PostCSS config. A minimal postcss.config.js:

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

Most modern toolchains (Vite, Next.js, webpack with postcss-loader) pick up this config automatically. You rarely wire autoprefixer up by hand; you tell PostCSS about it once and forget it exists.

Configure Browserslist, not autoprefixer

The mistake that produces surprising output is configuring the wrong thing. Autoprefixer has almost no options of its own that you should touch. What controls its behavior is your Browserslist configuration.

Define your targets in package.json or a .browserslistrc file:

> 0.5%
last 2 versions
not dead

That query says: browsers with more than half a percent market share, the last two versions of each, excluding browsers that are no longer maintained. Autoprefixer reads it and prefixes accordingly. Change the query and you change the prefixes, with no autoprefixer edits at all.

Two habits keep this predictable:

  • Commit a single Browserslist config and reuse it. Autoprefixer, postcss-preset-env, and bundlers all read the same source of truth, so define it once.
  • Keep the Can I Use data current. The support data lives in the caniuse-lite package. Stale data means autoprefixer makes decisions based on an old snapshot of the browser world. Run npx update-browserslist-db@latest periodically to refresh it.

Is npm autoprefixer a security risk?

Autoprefixer runs at build time and produces static CSS. It does not execute in the user's browser, does not touch your runtime, and does not process untrusted input in production. That places it in the build-toolchain risk category rather than the runtime-vulnerability category.

That does not mean it is risk-free. Any package your build pulls in runs with the privileges of your build environment, which often includes access to environment variables, source code, and sometimes deployment credentials. A compromised build dependency is a real supply-chain attack vector, and the front-end toolchain has a deep transitive tree.

Practical controls:

  • Pin versions with a lockfile so the same code builds the same tree every time.
  • Scan your dev dependencies, not just runtime ones. Build-time packages are frequently excluded from scans, which is exactly where an attacker would prefer to hide. An SCA tool such as Safeguard can flag a known-bad version anywhere in the graph; our SCA product treats dev dependencies as in scope by default.
  • Refresh caniuse-lite deliberately rather than letting a broad npm update churn your whole tree at once.

For the broader reasoning on why build-time dependencies deserve the same scrutiny as runtime ones, the academy has a piece on securing the front-end supply chain.

When you do not need autoprefixer

Worth stating plainly: if you target only evergreen browsers and use modern CSS that no longer needs prefixes, autoprefixer may add almost nothing. The safest dependency is the one you do not include. Before adding autoprefixer npm out of habit, check whether your Browserslist targets actually require any prefixes for the features you use. If your output diff is empty, you have your answer.

That said, for any project supporting a realistic spread of browsers, autoprefixer remains the low-effort, correct default, and the maintenance burden it removes far outweighs the small supply-chain surface it adds.

FAQ

What does npm autoprefixer do?

It is a PostCSS plugin that automatically adds vendor prefixes (like -webkit- and -moz-) to your CSS based on the browsers you target. You write standard, unprefixed CSS and autoprefixer inserts the prefixes needed for your Browserslist configuration at build time.

Should autoprefixer be a dependency or devDependency?

A devDependency. Autoprefixer runs during your build and produces static CSS; nothing from the package ships to end users at runtime. Install it with npm install autoprefixer postcss --save-dev.

How do I control which prefixes autoprefixer adds?

Through Browserslist, not autoprefixer options. Define your target browsers in a .browserslistrc file or the browserslist key in package.json, and keep the caniuse-lite data current with npx update-browserslist-db@latest.

Is autoprefixer a supply-chain security concern?

It is a build-time dependency, so it does not run in production, but it executes with your build environment's privileges. Pin it with a lockfile, include dev dependencies in your vulnerability scans, and refresh its browser data deliberately rather than through broad, untracked updates.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.