Skip to content
Merged
Changes from 10 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions src/content/guides/native-css.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title: Native CSS
sort: 27
contributors:
- alexander-akait
---

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

T> `experiments.css` is still experimental. It is expected to become the default in webpack v6, but behavior can still change while development continues.

## Getting Started

Enable native CSS support in your webpack configuration:

**webpack.config.js**

```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**

```js
import "./styles.css";

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

**src/styles.css**

```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**

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

**src/index.js**

```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);
```

T> CSS Modules class names are exported. By default, named exports are enabled for CSS modules.

## 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**

```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**

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

### 3) Keep imports unchanged

Your JS imports can stay the same:

```js
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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add options (from css-loader and style-loader and mini-css-extract-plugin) for CSS modules here and how to migrate, most of options are already implemented, some of them should be solved in other way, feel free to start from css-loader, then mini-css-extract-plugin and then style-loader, you can find all supported options here:

style-loader now is exportType: "style"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I updated it

Loading