A toolkit for making CSS Modules useful.
By default, CSS Modules have limited language features in editors. For example:
- Clicking on
styles.buttondoes not "Go to Definition" inButton.module.css. - Renaming
styles.buttonmodifies the code inButton.tsxbut not inButton.module.css. - Performing "Find All References" for
styles.buttonfinds references inButton.tsx, not inButton.module.css.
It has been difficult to solve these issues because the TypeScript Language Server (tsserver) does not load CSS files. TSServer does not know which part of the code to "Go to Definition" for, nor which part of the code to rename.
CSS Modules Kit solves this problem by using the TypeScript Language Service Plugin and Volar.js. They extend tsserver to load *.module.css files. As a result, rich language features become available. Moreover, it works with various editors.
In addition, CSS Modules Kit provides various tools for CSS Modules (e.g., codegen, linter-plugin). CSS Modules Kit provides you everything you need. It saves you from the hassle of combining multiple third-party tools.
See docs/get-started.md.
- Open https://stackblitz.com/~/github.com/mizdra/css-modules-kit-example
- After waiting a moment, a message will appear in the bottom-right saying
you want to install the recommended extensions. ClickInstalland wait for the installation to complete. - Open
src/a.tsx. CSS Modules language features should now be enabled.
@css-modules-kit/ts-plugin@css-modules-kit/codegen@css-modules-kit/stylelint-plugin@css-modules-kit/eslint-plugin
Go to Definition
2024-12-22.2.05.16.mov
Rename Symbol
2024-12-22.2.13.35.mov
Find All References
2024-12-22.2.10.01.mov
Definition Preview by Hover
You can preview the definition with Command + Hover on macOS and VS Code (key bindings may vary depending on your OS and editor).
2025-06-16.0.25.40.mov
Automatically update import statements when moving `*.module.css`
2024-12-26.20.24.48.mov
Create CSS Module file for current file
If there is no CSS Module file corresponding to xxx.tsx, create one.
2025-02-02.19.07.06.mov
Complete `className={...}` instead of `className="..."`
In projects where CSS Modules are used, the element is styled with className={styles.xxx}. However, when you type className, className="..." is completed. This is annoying to the user.
Therefore, instead of completing className="...", it should complete className={...}.
2025-02-02.19.07.27.mov
Prioritize the `styles' import for the current component file
When you request styles completion, the CSS Module file styles will be suggested. If there are many CSS Module files in the project, more items will be suggested. This can be confusing to the user.
So I have made it so that the styles of the CSS Module file corresponding to the current file is shown first.
Add missing CSS rule
If you are trying to use a class name that is not defined, you can add it with Quick Fixes.
2025-02-02.19.24.36.mov
css-modules-kit uses tsconfig.json as its configuration file. This configuration only affects the ts-plugin and codegen.
Type: boolean, Default: true
Enables or disables css-modules-kit. When set to false, codegen will exit with an error. Currently, both codegen and the ts-plugin will work even if this option is omitted, but in the future, they will not work unless this option is set to true. For more details, see #289.
Type: string, Default: "generated"
Specifies the directory where *.d.ts files are output.
{
"compilerOptions": {
// ...
},
"cmkOptions": {
"dtsOutDir": "generated/cmk",
},
}Type: boolean, Default: false
Determines whether to generate *.module.d.css.ts instead of *.module.css.d.ts.
{
"compilerOptions": {
// ...
},
"cmkOptions": {
"arbitraryExtensions": true,
},
}Type: boolean, Default: false
Determines whether to generate named exports in the d.ts file instead of a default export.
{
"compilerOptions": {
// ...
},
"cmkOptions": {
"namedExports": true,
},
}Type: boolean, Default: false
Whether to prioritize named imports over namespace imports when adding import statements. This option only takes effect when cmkOptions.namedExports is true.
When this option is true, import { button } from '...' will be added. When this option is false, import button from '...' will be added.
{
"compilerOptions": {
// ...
},
"cmkOptions": {
"namedExports": true,
"prioritizeNamedImports": true,
},
}Type: boolean, Default: true
Determines whether to generate the token of keyframes in the d.ts file.
{
"compilerOptions": {
// ...
},
"cmkOptions": {
"keyframes": false,
},
}Due to implementation constraints and technical reasons, css-modules-kit has various limitations.
- Sass and Less are not supported.
- If you want to use Sass and Less, please use happy-css-modules. Although it does not offer as rich language features as css-modules-kit, it provides basic features such as code completion and Go to Definition.
- The name of classes,
@value, and@keyframesmust be valid JavaScript identifiers.- For example,
.fooBarand.foo_barare supported, but.foo-baris not supported. - See #176 for more details.
- For example,
- The specifiers in
@import '<specifier>'and@value ... from '<specifier>'are resolved according to TypeScript's module resolution method.- This may differ from the resolution methods of bundlers like Turbopack or Vite.
- If you want to use import aliases, use
compilerOptions.pathsorimportsinpackage.json.- Example:
"paths": { "@/*": ["src/*"] }
- Example:
- If you want to omit
.css, usecompilerOptions.moduleSuffixes.- Example:
"moduleSuffixes": [".css", ""]
- Example:
- If you want to resolve the
stylecondition, usecompilerOptions.customConditions.- Example:
"customConditions": ["style"]
- Example:
:local .foo {...}is not supported.- Use
:local(.foo) {...}instead.
- Use
:global .foo {...}is not supported.- Use
:global(.foo) {...}instead.
- Use
@keyframes :local(foo) {...}is not supported.- Use
@keyframes foo {...}instead. - Meanwhile,
@keyframes :global(foo) { ... }is supported.
- Use
- VS Code for Web is not supported.
Viijay-Kr/react-ts-css also provides rich language features for CSS Modules. However, it is implemented using the VS Code Extension API. Therefore, it only supports VS Code.
On the other hand, css-modules-kit is implemented using the TypeScript Language Service Plugin. It is a technology that does not depend on the editor. css-modules-kit supports editors other than VS Code.
mrmckeb/typescript-plugin-css-modules is also implemented using the TypeScript Language Service Plugin. However, it only supports basic language features such as completion, typed styles, and Go to Definition. Cross-file language features between *.tsx and .module.css—such as Rename and Find All References—are not supported.
This is because mrmckeb/typescript-plugin-css-modules does not extend tsserver to handle *.module.css files. Due to the lack of information about *.module.css files, tsserver cannot provide cross-file language features between *.tsx and .module.css.
On the other hand, css-modules-kit extends tsserver to handle *.module.css files. The extension is realized by Volar.js. Please read the following slides for details (in Japanese).

{ "compilerOptions": { // ... }, "cmkOptions": { "enabled": true, }, }