How to use CSS Modules with TypeScript and webpack

Using CSS Modules with TypeScript is not as obvious as with JavaScript. The reason is that TypeScript has special treatment for imports and if you try to use CSS Modules the same way you did in JavaScript:

import s from './Button.css';

You’ll get an error: “Cannot find module './Button.css'”. There are several ways to fix that.

The easy way

You can bypass TypeScript import magic by using require instead of import:

const s = require('./Button.css');

It’s processed by webpack as usual but you won’t have type check and autocomplete for CSS class names.

The better way

To use import you need typings for CSS. For example, you have Button.css like this:

.foo {
  color: chocolate;
}
.barBaz {
  color: tomato;
}

Now you need Button.css.d.ts like this:

export const foo: string;
export const barBaz: string;

typings-for-css-modules-loader is a drop-in replacement for css-loader that generates typings for CSS on the fly. Let’s install it:

npm install --save-dev typings-for-css-modules-loader

Then update your webpack config:

module: {
  rules: [
    {
      test: /\.css$/,
      include: path.join(__dirname, 'src/components'),
      user: [
        'style-loader',
        {
          loader: 'typings-for-css-modules-loader',
          options: {
            modules: true,
            namedExport: true
          }
        }
      ]
    }
  ]
}

Now you can import styles like this:

import * as s from './Button.css';

Type check and autocomplete will work as expected:

Leave your comments on Medium. You can improve this post by editing it on GitHub.

About me

I’m a frontend developer living in Berlin, Germany. I work at Here, and in my spare time I love making photos, writing, hanging out with my dogs and drinking lots of coffee.

Check out my projects, follow me on Twitter or ask me anything.