Native CSS

This guide shows how to use webpack native CSS handling with experiments.css.

Getting Started

Enable native CSS support in your webpack configuration:

webpack.config.js

export default {
  experiments: {
    css: true,
  },
};

With this option enabled, webpack can process CSS without adding css-loader and mini-css-extract-plugin for the basic flow.

Importing CSS

After enabling the experiment, import .css files directly from JavaScript:

src/index.js

import "./styles.css";

const element = document.createElement("h1");
element.textContent = "Hello native CSS";
document.body.appendChild(element);

src/styles.css

h1 {
  color: #1f6feb;
}

Webpack will process the CSS and include it in the build output.

CSS Modules

Native CSS support also includes CSS Modules. Use the .module.css extension:

src/button.module.css

.button {
  background: #0d6efd;
  color: white;
  border: 0;
  border-radius: 4px;
  padding: 8px 12px;
}

src/index.js

import * as styles from "./button.module.css";

const button = document.createElement("button");
button.className = styles.button;
button.textContent = "Click me";
document.body.appendChild(button);

Production Build

With experiments.css: true, webpack provides native CSS extraction and content hashing for CSS assets in production builds.

Compared to the classic setup:

  • Traditional approach: css-loader + mini-css-extract-plugin
  • Native approach: experiments.css with built-in extraction behavior

This reduces configuration and keeps the CSS pipeline closer to webpack core features.

Experimental Status & Known Limitations

experiments.css is explicitly experimental, so treat it as opt-in and test carefully before broad rollout.

Known points to keep in mind:

  • APIs and behavior may still evolve before webpack v6 defaults.
  • Some loader-specific options are not part of native CSS behavior (for example, loader-specific filters).
  • If your project relies on advanced loader chains, validate each part before migrating fully.

Migration Guide

If you currently use css-loader and mini-css-extract-plugin, migrate in small steps.

1) Start from a classic setup

webpack.config.js

import MiniCssExtractPlugin from "mini-css-extract-plugin";

export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

2) Switch to native CSS

webpack.config.js

export default {
  experiments: {
    css: true,
  },
};

3) Keep imports unchanged

Your JS imports can stay the same:

import "./styles.css";
import * as styles from "./button.module.css";

4) Validate output in development and production

Check that:

  • styles are applied correctly in development,
  • generated CSS files are emitted for production,
  • CSS Modules exports match your existing usage.
Edit this page·

1 Contributor

alexander-akait