CSS
Rstest can either process styles with the Rsbuild toolchain or replace style imports when a test does not depend on them. Choose the setup based on what the test needs to verify:
Process styles in tests
Node.js tests
Rstest has built-in support for CSS and CSS Modules. In Node.js tests, including jsdom and happy-dom, it processes CSS without emitting CSS assets by default:
- Regular CSS files do not produce style assets.
- CSS Modules export class name mappings that component tests can use.
- Without a matching loader or resource type, ordinary
.less,.scss, and.sassimports export an empty string (''). No preprocessor plugin is needed for these imports. - When a Less or Sass plugin is enabled, its processing and options remain effective. Compilation errors are still reported.
The fallback also applies to .module.less, .module.scss, and .module.sass: their default export is {}, so styles.button is undefined. Enable a preprocessor plugin when you need real class name mappings, or replace style imports when you want a property-name proxy.
User loaders, aliases, and resource types retain their behavior. Imports with a query, such as ?raw or ?url, require a matching plugin or rule and do not use the fallback. Style files must still exist; the fallback does not replace unresolved imports.
For example, .css and .module.css imports work without additional CSS configuration:
CSS Modules commonly use filenames such as .module.css, .module.less, or .module.scss. Use output.cssModules to customize class name generation and other CSS Modules options.
Add CSS preprocessor support
To compile preprocessor styles, enable a corresponding Rsbuild plugin. The examples below cover Less and Sass. For another preprocessor, check the Rsbuild plugin list for a matching plugin and register it in the same way. Install only the plugins required by the styles under test.
@rsbuild/plugin-less compiles .less and .module.less files:
@rsbuild/plugin-sass compiles .sass, .scss, .module.sass, and .module.scss files:
If your project reuses an Rsbuild config through @rstest/adapter-rsbuild, configure these plugins in rsbuild.config.ts instead of duplicating them in rstest.config.ts.
If you use @rstest/adapter-rspack, the Rsbuild plugin and output.cssModules examples above do not apply. This adapter uses the CSS rules from rspack.config.ts, so configure Less, Sass, and CSS Modules there.
Browser mode
Node.js tests can verify imported values, but styles do not participate in page rendering. Use Browser Mode when a test needs computed styles, layout, or visual behavior. Browser Mode runs the component and its styles in a real browser. It does not use the Node.js empty-style fallback; Less and Sass require their corresponding plugin or loader.
Replace styles in logic tests
If a Node.js test only checks component logic, it can replace style imports with test substitutes. This avoids installing a Less or Sass plugin and skips CSS preprocessing, but it also means the test cannot validate the replaced styles.
Replace specific imports with an alias
For a small number of known CSS Modules imports, use resolve.alias with identity-obj-proxy. The package returns each requested property name as its value, so styles.button returns button.
The $ suffix makes the alias match the complete import request. It is a marker in the alias key and is not part of the import path.
resolve.alias matches string prefixes, not regular expressions. Use it when the source has a small, stable set of style import requests. The alias can also point to a local stub module; for example, an empty module is enough for a side-effect-only import such as import './reset.less'.
Replace style imports by extension
For many style imports, use NormalModuleReplacementPlugin to replace files by extension. The following Node.js setup replaces both CSS Modules and side-effect-only style imports with identity-obj-proxy:
Both replacement approaches bypass style resolution and compilation. Keep their tradeoffs in mind:
styles.buttonreturnsbutton, not the generated class name from a real build.- Less, Sass, and CSS Modules syntax is not validated.
- Missing or misspelled style files are not detected because the import is replaced before the original file is resolved.
- Features such as
composes,:global, emitted styles, and client/server class name consistency cannot be tested.
Use real style processing when any of these behaviors matter, and use Browser Mode when the assertion depends on rendered styles.