CSS and HTML Are Built In
If you set up a webpack project today by following an older tutorial, you will install css-loader, style-loader, mini-css-extract-plugin, html-loader and html-webpack-plugin. You don't need any of them anymore. Since webpack 5.109.0, CSS and HTML are built in, stable and on by default — with no configuration.
- What you can remove
- CSS with no configuration
- Sass, Less, PostCSS and Tailwind
- HTML pages with no plugin
- Existing projects keep working
What you can remove
| Package | Replaced by |
|---|---|
css-loader | Built-in CSS parsing, @import / url() resolution and CSS Modules |
style-loader | exportType: "style" |
mini-css-extract-plugin | Built-in extraction — a .css file per chunk, by default |
css-minimizer-webpack-plugin | Built-in CSS minification and vendor prefixes (5.110.0+) |
html-loader | Importing .html from JavaScript |
html-webpack-plugin | An HTML entry or output.html |
html-minimizer-webpack-plugin | Built-in HTML minification (5.110.0+) |
These packages are deprecated. Preprocessors and template engines — sass-loader, less-loader, postcss-loader, Pug and friends — are not; they keep working, in front of the built-in support.
CSS with no configuration
Import a stylesheet and webpack does the rest:
import "./styles.css";
import * as button from "./button.module.css";Webpack resolves @import and url(), scopes *.module.css files as CSS Modules and extracts a .css file for each chunk. In mode: "production" (webpack 5.110.0 or later) it minifies the CSS, and with a browserslist target it also adds the vendor prefixes those browsers need. No module.rules, no plugin.
Sass, Less, PostCSS and Tailwind
Keep the preprocessor's loader and drop the CSS loaders behind it. The rule's type hands its output to webpack's CSS pipeline:
{
test: /\.s[ac]ss$/i,
- use: ["style-loader", "css-loader", "sass-loader"],
+ use: ["sass-loader"],
+ type: "css/auto",
}One rule covers both layout.scss (global) and button.module.scss (a CSS Module). For PostCSS and Tailwind on .css files, and the few cases where experiments.css: true is needed, see Preprocessors, PostCSS and Tailwind.
HTML pages with no plugin
Point an entry at a page and webpack builds it — every <script>, <link>, <img> and inline <style> it references is bundled, and its URLs are rewritten to the hashed files:
export default {
entry: "./src/index.html",
};For a project with a JavaScript entry, output.html: true generates the page and links its scripts and stylesheets. The Native HTML guide covers titles, favicons, Subresource Integrity, CSP and the rest.
Existing projects keep working
experiments.css and experiments.html default to 'auto': when a rule in your module.rules already gives .css or .html files a loader or an explicit type, the built-in support for that file type stays off for the whole build. An existing css-loader or html-loader setup therefore keeps building exactly as before.
To migrate one rule at a time, set experiments.css: true (or experiments.html: true) and give the rules that still use the old loaders type: "javascript/auto", so the built-in support leaves their files to them.
To migrate CSS, run the codemod:
npx codemod @webpack/css-plugins-to-native-cssor follow the Native CSS and Native HTML migration guides. New projects scaffolded with npx create-webpack-app already use the built-in support.



