For AI agents: the complete documentation index is available at https://rspack.rs/llms.txt, the full documentation bundle is available at https://rspack.rs/llms-full.txt, and this page is available as Markdown at https://rspack.rs/guide/languages/css.md.
close

CSS

Rspack has built-in support for CSS and provides several features to support CSS bundling.

Built-in CSS support

Rspack supports the following four CSS Modules types which you can configure manually:

  • css/auto: Automatically determines whether a file is a normal CSS file or CSS Modules based on the file extension. Files ending with *.module.css or *.modules.css are treated as CSS Modules.
  • css: Used to handle normal CSS files without CSS Modules features.
  • css/global: Used to handle CSS Modules in global scope mode.
  • css/module: Used to handle CSS Modules.

The difference between css/auto, css/global, and css/module is how CSS Modules scope affects the generated CSS:

  • css/auto chooses the behavior by filename. style.css is handled as plain CSS, while style.module.css and style.modules.css are handled like css/module.
  • css/module enables CSS Modules with local scope by default. A selector like .button is renamed in the generated CSS. Use :global(.button) when you want a selector to stay global.
  • css/global enables CSS Modules with global scope by default. A selector like .button stays global. Use :local(.button) when you want a selector to be renamed in the generated CSS.

For example:

style.css
.button {
  color: red;
}

:local(.title) {
  color: blue;
}

With type: 'css', the file is emitted as plain CSS without applying CSS Modules scope transforms.

With type: 'css/module', .button and .title are local selectors and are renamed in the generated CSS. Use :global(.button) if .button should stay global.

With type: 'css/global', .button stays global, while .title is renamed because it is wrapped in :local(...).

The generated CSS would look like this:

css/auto style.css
css/auto style.module.css
css/module style.css
css/global style.css
.button {
  color: red;
}

:local(.title) {
  color: blue;
}

To enable CSS support, add CSS rules to your configuration:

rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.module\.css$/i,
        type: 'css/module',
      },
      {
        test: /\.global\.css$/i,
        type: 'css/global',
      },
      {
        test: /\.css$/i,
        type: 'css/auto',
      },
    ],
  },
};

You can also configure type: 'css/auto' to customize which files are treated as CSS files. For example, treat .less files as CSS files:

rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.less$/,
        type: 'css/auto', // 👈
        use: ['less-loader'],
      },
    ],
  },
};

CSS export type

Built-in CSS support uses exportType: 'link' by default. This emits CSS as stylesheet output and loads it with the built-in CSS loading runtime. You can set module.parser.css.exportType or the parser options for css/auto, css/global, and css/module to change how CSS is exported to JavaScript.

Supported values:

  • link: emit CSS as stylesheet output.
  • text: export the generated CSS text as the default export.
  • css-style-sheet: export a CSSStyleSheet instance as the default export.
  • style: inject CSS into the document through <style> tags at runtime.
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        type: 'css/auto',
        parser: {
          exportType: 'text',
        },
      },
    ],
  },
};
index.js
import cssText from './style.css';

console.log(cssText);

See module.parser["css/auto"].exportType for details.

CSS entry

With the default exportType: 'link', you can use a CSS file as an entry to emit a stylesheet without a corresponding JavaScript entry file. For example:

rspack.config.mjs
export default {
  entry: './src/styles.css',
  module: {
    rules: [{ test: /\.css$/i, type: 'css' }],
  },
};

This configuration emits only dist/main.css. Referenced assets or source maps, if configured, may add output files. See output.cssFilename to customize the stylesheet filename.

External resources

With built-in CSS support, you can use externals to keep CSS imports and assets out of the bundle. Use the css-import external type for an @import and the asset-url type for a url() reference:

style.css
@import './theme.css';

.logo {
  background-image: url('./logo.svg');
}
rspack.config.mjs
export default {
  externals: {
    './theme.css': 'css-import https://example.com/theme.css',
    './logo.svg': 'asset-url https://example.com/logo.svg',
  },
};

The generated CSS refers to the external URLs instead of bundling the files. The browser loads those resources when it loads the stylesheet.

For the default web target, HTTP(S) and protocol-relative URLs in CSS are external by default. Enabling experiments.buildHttp can change how HTTP(S) URLs are handled.

Magic comments

With built-in CSS support, add /* rspackIgnore: true */ to an @import or url() reference to leave it unchanged instead of resolving and bundling it. Place the comment after @import or immediately before url():

@import /* rspackIgnore: true */ url('/styles/theme.css');

.logo {
  background-image: /* rspackIgnore: true */ url('/images/logo.svg');
}

Rspack does not emit the ignored resources, so they must be available at the URLs used at runtime. /* webpackIgnore: true */ is also supported for webpack compatibility.

To disable processing for all @import rules or url() references, see the CSS parser options import and url.

Using css-loader

You can use css-loader with CssExtractRspackPlugin to generate standalone CSS files, or with style-loader to inject styles at runtime.

Using CssExtractRspackPlugin

Rspack supports using css-loader and CssExtractRspackPlugin to generate standalone CSS files.

If you are migrating a webpack project that uses mini-css-extract-plugin, it is recommended to replace it with CssExtractRspackPlugin. Their functionality and options are basically the same.

  • Install css-loader:
npm
yarn
pnpm
bun
deno
npm add css-loader -D
  • Add configuration:
rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [rspack.CssExtractRspackPlugin.loader, 'css-loader'],
        type: 'javascript/auto',
      },
    ],
  },
  plugins: [new rspack.CssExtractRspackPlugin({})],
};

Refer to the migration guide to learn how to migrate from webpack.

Tip

CssExtractRspackPlugin cannot be used with type: 'css', type: 'css/auto', type: 'css/global', or type: 'css/module' as these types are provided by native css support.

Using style-loader

Rspack supports using css-loader and style-loader to inject CSS via <style> tags. This method does not generate standalone CSS files but inline the CSS content into JS files.

  • Install css-loader and style-loader:
npm
yarn
pnpm
bun
deno
npm add css-loader style-loader -D
  • Add configuration:
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
        type: 'javascript/auto',
      },
    ],
  },
};
Tip

style-loader cannot be used with type: 'css', type: 'css/auto', type: 'css/global', or type: 'css/module' as these types are provided by native css support.

CSS Modules

CSS Modules is a way of organizing CSS files that localizes the scope of CSS by automatically generating unique identifiers for class names. This allows you to use the same class name in different files without worrying about collisions.

Built-in support

If you enable Built-in CSS support, Rspack will treat files with a *.module.css extension as CSS Modules by default. You can import them into your JavaScript files, and then access each class defined in the CSS file as an export from the module.

index.module.css
.red {
  color: red;
}

You can use namespace import:

index.js
import * as styles from './index.module.css';
document.getElementById('element').className = styles.red;

You can also use named import:

import { red } from './index.module.css';
document.getElementById('element').className = red;

To enable default imports in Rspack, you need to set namedExports to false in your Rspack configuration file. This allows you, when using CSS Modules, to import the entire style module by default import, in addition to namespace imports and named imports:

rspack.config.mjs
export default {
  module: {
    parser: {
      'css/auto': {
        namedExports: false,
      },
    },
  },
};

Now you can use default import:

import styles from './index.module.css';
document.getElementById('element').className = styles.red;
Tip

Rspack provides options to customize the parsing and generation of CSS Modules:

Using css-loader

If you do not enable Rspack's built-in CSS support, you can use css-loader to provide CSS Modules support.

Enable the modules option of css-loader:

rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: 'css-loader',
        type: 'javascript/auto',
        options: {
          modules: true,
        },
      },
    ],
  },
};

For more usage, please refer to css-loader - modules.

PostCSS

Rspack supports postcss-loader, which you can configure like this:

npm
yarn
pnpm
bun
deno
npm add postcss postcss-loader -D
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                // ...
              },
            },
          },
        ],
        // set to 'css/auto' if you want to support '*.module.css' as CSS Modules, otherwise set type to 'css'
        type: 'css/auto',
      },
    ],
  },
};

The above configuration will have all *.css files processed by postcss-loader. The output will be passed to Rspack for CSS post-processing.

Tailwind CSS

Tailwind CSS is a CSS framework that provides utility classes for styling components.

For Tailwind CSS v4 and later, use the @tailwindcss/webpack loader with Rspack's built-in CSS support:

npm
yarn
pnpm
bun
deno
npm add tailwindcss @tailwindcss/webpack -D
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        type: 'css',
        use: ['@tailwindcss/webpack'],
      },
    ],
  },
};

Import Tailwind CSS in your stylesheet:

src/styles.css
@import 'tailwindcss';

To use css-loader and CssExtractRspackPlugin instead, install css-loader and use the following configuration:

npm
yarn
pnpm
bun
deno
npm add css-loader -D
rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          rspack.CssExtractRspackPlugin.loader,
          'css-loader',
          '@tailwindcss/webpack',
        ],
      },
    ],
  },
  plugins: [new rspack.CssExtractRspackPlugin()],
};

For Tailwind CSS v3, see Install Tailwind CSS v3 with Rspack.

Sass

Rspack supports sass-loader, which you can configure like this:

npm
yarn
pnpm
bun
deno
npm add sass-embedded sass-loader -D
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.(sass|scss)$/,
        use: [
          {
            loader: 'sass-loader',
            options: {
              // using `modern-compiler` and `sass-embedded` together significantly improve build performance,
              // requires `sass-loader >= 14.2.1`
              api: 'modern-compiler',
              implementation: require.resolve('sass-embedded'),
            },
          },
        ],
        // set to 'css/auto' if you want to support '*.module.(scss|sass)' as CSS Modules, otherwise set type to 'css'
        type: 'css/auto',
      },
    ],
  },
};

The above configuration runs all *.sass and *.scss files through the sass-loader and passes the resulting results to Rspack for CSS post-processing.

Less

Rspack supports less-loader, which you can configure like this:

npm
yarn
pnpm
bun
deno
npm add less less-loader -D
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'less-loader',
            options: {
              // ...
            },
          },
        ],
        // set to 'css/auto' if you want to support '*.module.less' as CSS Modules, otherwise set type to 'css'
        type: 'css/auto',
      },
    ],
  },
};

The above configuration runs all *.less files through the less-loader and passes the generated results to Rspack for CSS post-processing.