A toolkit for making CSS Modules useful.
By default, CSS Modules have limited language features in editors. For example:
- Clicking on
styles.button
does not go to its definition inButton.module.css
. - Renaming
styles.button
does not rename the corresponding.button {...}
inButton.module.css
. - Find all references of
styles.button
does not include its definition inButton.module.css
.
It has been difficult to solve these issues because the TypeScript Language Server (tsserver) does not handle CSS files. Since tsserver does not load CSS files, it cannot determine which definitions to go to or which code to rename.
css-modules-kit solves this problem by using the TypeScript Language Service Plugin. css-modules-kit extends tsserver to handle *.module.css
files using it. As a result, rich language features like code navigation and rename refactoring become available. Moreover, it works with various editors.
css-modules-kit also provides various development tools for CSS Modules. For example, stylelint plugins and the tool that generates *.d.ts
files.
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.
So, instead of className="..."
instead of className={...}
instead of 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
Please read the Get Started guide.
- Open this repository with VS Code
- Open
Run and Debug
menu - Select
vscode (1-basic)
configuration and start debugging
css-modules-kit uses tsconfig.json
as its configuration file.
In TypeScript, the include
/exclude
properties specify which *.ts
files to compile. css-modules-kit reuses these options to determine which *.module.css
files to handle with codegen and ts-plugin. Therefore, make sure your *.module.css
files are included in the include
or exclude
settings.
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,
},
}
:local(...)
and:global(...)
@keyframes <name> { ... }
@value <name>: <value>;
@value <name>[, <value>]+ from <module-specifier>;
@import <module-specifier>;
To simplify the implementation, some features are not supported.
- 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@keyframes
must be valid JavaScript identifiers.- For example,
.fooBar
and.foo_bar
are supported, but.foo-bar
is not supported. - See #176 for more details.
- For 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).