Do you really need types for CSS modules?
Tags: cssmodules, css, typescript, webpack
Published: 2023-11-14 13:39:35

Some teams that use CSS modules + typescript on their projects often consider having type generation for the CSS class names.

File-wise it looks like this:

```
my-feature.tsx
my-feature.module.scss
my-feature.module.scss.d.ts <-- generated types
```

The setup for such type generation is well-described in [this article](https://medium.com/@sapegin/css-modules-with-typescript-and-webpack-6b221ebe5f10) _with the only exception that the plugin which is recommended in the article is no longer supported and I'd use [this one](https://github.com/TeamSupercell/typings-for-css-modules-loade) instead._

Let's review the pros and cons of having such type generation on a project. 

## Pros ✅

When it comes to using TypeScript with CSS modules, the idea of generating types for class names has its merits.

#### Superior autocomplete

  With type generation, you get superior autocomplete that functions universally without the need for extra plugins.

  _However, if you don't generate types,_ WebStorm IDE already provides autocomplete. And Visual Studio Code users, as always, can install [the CSS modules plugin](https://marketplace.visualstudio.com/items?itemName=clinyong.vscode-css-modules) to have it. 

#### Typo-Safe development

  Type generation makes your development process typo-safe. It immediately throws a type error if you happen to mistype a class name. This not only helps catch errors early in your IDE but ensures these issues are reported during CI processes, providing a robust safety net.

_However, if you don't generate types,_ wouldn't you take a look that your CSS changes have an effect anyway? 

## Cons ❌

#### New and unused code has no types generated

Webpack is a smart tool and it is good for discarding unused code. Types are not generated for the unused code, which could be confusing especially when writing new code. The code generation won't kick in until your component, that imports the CSS file is properly imported somewhere.

{% embed https://www.youtube.com/embed/iHpE3bdS29w %}

#### Delayed updates

Regenerating types and updating the IDE takes some time. While not a major hurdle, it adds a step to your development workflow.

#### Jump to declaration gets worse

The "jump to declaration" feature in IDEs might lead you to the TypeScript file instead of the corresponding SCSS file, which is quite annoying. I don't know how to fix this in webstorm, but VSCode has a [plugin](https://marketplace.visualstudio.com/items?itemName=viijay-kr.react-ts-css) (of course).

{% embed https://www.youtube.com/embed/4T1pz6iQLDI %}

#### One more webpack plugin

To enable this setup you'll need one more dependency, one more plugin in your configuration. It is also [recommended](https://github.com/TeamSupercell/typings-for-css-modules-loader#webpack-rebuilds--builds-slow) to ignore watching the generated files by applying webpack.WatchIgnorePlugin. It is not a big deal, but it adds the slightest new complexity to your webpack config for the sake of generating types.

## Conclusion:

So with that being said, I think the pros of types generating for CSS modules aren't really that big considering the downsides. This tooling might stand in your way sometimes, instead of making your work more productive.

Without types generating, autocomplete is OK out of the box in webstorm (and vscode has a plugin). "Typo-safety" is nice, but when working with CSS you're normally supposed to give your changes a look anyway so you'll know quickly if something went wrong, or, perhaps, you have visual regression tests that can help you out. 

Of course, this all depends on your team's priorities and preferences. I, personally, really like how types help to highlight when classes are applied for no reason in code without any CSS attached to them. But I also don't like that "jump to declaration" doesn't navigate me to the CSS file in webstorm. So for smaller projects, I might prefer skipping the type generation for CSS modules.