Skip to main content
Extension.js supports CSS modules with zero configuration for module-style filenames (for example, styles.module.css). It routes them through the Rspack CSS pipeline. Class names stay locally scoped to the component that imported them.

When CSS modules are a good fit

  • You need local class scoping without adopting a full CSS-in-JS stack.
  • You share components across popup/options/new-tab surfaces.
  • You want predictable style ownership in larger extension codebases.

Template examples

content-css-modules

content-css-modules template screenshot Add locally scoped styles to content-script UI with minimal setup.
npx extension@latest create my-extension --template=content-css-modules
Repository: extension-js/examples/content-css-modules

Usage with an existing extension

To use CSS modules, name files with a module suffix:
  • *.module.css
  • *.module.scss
  • *.module.sass
  • *.module.less
Use the related language pages for Sass and Less setup requirements.
- myComponentCss.css
+ myComponentCss.module.css

Usage example

After renaming your stylesheet, import and use it in your component:
import styles from './styles/myComponent.module.css'

const button = document.createElement('button')
button.className = styles.primary
button.innerText = 'Click here'
document.body.appendChild(button)

How it works

Extension.js enables Rspack CSS support and handles module imports through the CSS module pipeline:
  • Default import style maps (import styles from "./x.module.css")
  • Rspack generates scoped class names through its CSS module pipeline
  • Module class exports work directly in JS/TS/TSX files
In extension page contexts (for example, popup/options/new tab), module imports produce unique, scoped class names as expected.

Content script note

In content scripts, Extension.js emits CSS as stylesheet content without JavaScript class-name mappings. Use component-level local class naming in content scripts. Do not assume CSS module class imports work there unless you have explicitly tested it.

React/Preact example usage

For React or Preact, you can import and use the CSS module in the component like this:
import styles from './styles/myComponent.module.css'

export default function NewTabPage() {
  return <button className={styles.primary}>Click here</button>
}

Vue example usage

In Vue, you can use module classes from single-file component (SFC) styles:
<template>
  <button :class="$style.primary">Click here</button>
</template>

<style module>
@import './styles/myComponent.module.css';
</style>

Svelte example usage

In Svelte, import module mappings and apply class names:
<script>
  import styles from "./styles/myComponent.module.css";
</script>

<button class={styles.primary}>Click here</button>

Best practices

  • Keep module styles close to components (Component.module.css) for easier ownership.
  • Use :global(...) sparingly and only for intentional global overrides.
  • Prefer module styles for extension pages and framework components where class mapping is explicit.

Next steps

Video walkthrough