DEV Community

Cover image for How does VuReact compile Vue 3's CSS Modules to React?
Ryan John
Ryan John

Posted on • Originally published at vureact.top

How does VuReact compile Vue 3's CSS Modules to React?

VuReact is a compiler toolchain for migrating from Vue to React — and for writing React with Vue 3 syntax.

In this article, we will look at how Vue SFC <style module> blocks are compiled into React code.

Before We Start

To keep the examples easy to read, this article follows two simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with CSS Modules in Vue 3.

Compilation Mapping

Module style transformation

Vue CSS Modules are transformed into a React-compatible module import format while preserving class-name mapping.

  • Vue
<!-- Component.vue -->
<template>
  <div :class="$style.container">Hello</div>
</template>

<style module>
.container {
  padding: 20px;
  background: #f5f5f5;
}
</style>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Component.jsx
import $style from './component-abc1234.module.css';

function Component() {
  return <div className={$style.container}>Hello</div>;
}
Enter fullscreen mode Exit fullscreen mode
/* component-abc1234.module.css */
.container {
  padding: 20px;
  background: #f5f5f5;
}
Enter fullscreen mode Exit fullscreen mode

As the example shows, Vue <style module> blocks are compiled into CSS Modules files, then used in React through module imports. That preserves the familiar $style.container access pattern and keeps module scoping intact.

Custom module names

CSS Modules also support named module imports.

  1. Default module name: $style -> $style
  2. Custom module name: <style module="custom"> -> custom
  • Vue
<!-- Component.vue -->
<template>
  <div :class="custom.container">Custom Module</div>
</template>

<style module="custom">
.container {
  margin: 10px;
  border: 1px solid #ccc;
}
</style>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Component.jsx
import custom from './component-xyz123.module.css';

function Component() {
  return <div className={custom.container}>Custom Module</div>;
}
Enter fullscreen mode Exit fullscreen mode

The generated code keeps the module import style consistent with Vue's usage while adapting it to React's module import conventions.

CSS Modules with scoped styles

CSS Modules can also be combined with scoped styles for stronger isolation.

  • Vue
<!-- Component.vue -->
<template>
  <div :class="$style.wrapper">
    <span :class="$style.text">Text Content</span>
  </div>
</template>

<style module scoped>
.wrapper {
  padding: 20px;
  background: #f8f8f8;
}

.text {
  color: #333;
  font-size: 16px;
}
</style>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
// Component.jsx
import $style from './component-abc123.module.css';

function Component() {
  return (
    <div className={$style.wrapper} data-css-abc123>
      <span className={$style.text} data-css-abc123>
        Text Content
      </span>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* component-abc123.module.css */
.wrapper[data-css-abc123] {
  padding: 20px;
  background: #f8f8f8;
}

.text[data-css-abc123] {
  color: #333;
  font-size: 16px;
}
Enter fullscreen mode Exit fullscreen mode

The combination of scoped plus CSS Modules gives you both module-level encapsulation and per-component style isolation.

Compilation summary

VuReact's CSS Modules compilation strategy shows a complete module-style migration path:

  1. CSS Modules are extracted into standalone .module.css files.
  2. Class mappings are preserved, including $style.className syntax.
  3. React-compatible module imports are generated automatically.

That lets the compiled React output keep Vue's CSS Modules experience while fitting naturally into React's module-based styling model.

Related Links

Top comments (0)