Storybook 7.0 + React.js + TailwindCSS + CSS modules + Typescript setup that #$%& works

21 February 2023

UPDATE: when writing this I have found THIS article, that, coincidentally, was also updated around the same time.


Setting up a storybook project should NOT be THAT hard. I mean, everyone uses Storybook, it’s the only viable option out there when working on a design system.

TailwindCSS is at the stage when it’s already gained the momentum. Even large companies are considering it. Practically EVERY front-end dev has already worked with it.

And CSS modules have beed out there for more that 6 years I believe. And even though in JavaScript terms it’s a dinosaur, a legacy, it’s very much not dead and still a top choice for many, including moi.

Not even going to say anything about Typescript and React. If you’re not using TS or never worked with TS today - you’re unemployable. And React is a standard.

Surely there should be an article somewhere on how to set all this up correctly. SURELY?!


Well, after 4 hours of googling and trial and error, I finally was able to crack this “OH SO UNUSUAL” tech stack setup. Here is the repo, and let me highlight two points.

Point 1: Webpack 5 builder and framework

Webpack 4 is still the default choice for Storybook, but Storybook has already released support for Webpack 5, so I see no reason why we’d stick to v4. Important note here is that since we’re updating the core property, we should also update the framework

// main.ts export default { framework: '@storybook/react-webpack5', core: { builder: '@storybook/builder-webpack5', }, }

Point 2: Don’t overwrite default Webpack rules, but add more instead

It (unfortunately!) became a habit for whatever reason, that if I need to add some custom loader, I exclude the default rule from the array and re-create it. We shouldn’t do that, because it messes up the Storybook config in a way that it becomes hard to unfuck it.

Because we need to add a PostCSS loader to our .css files, don’t try to re-create css rule with all the css-loader and style-loader etc., but just push that extra rule to the end of that array, and be done with it.

// main.ts export default { ... webpackFinal: async config => { config.module.rules.push({ test: /\.css$/, use: [ { loader: 'postcss-loader', options: { postcssOptions: { plugins: { tailwindcss: {}, autoprefixer: {} }, }, }, }, ], include: path.resolve(__dirname, '../'), }) return config }, ... }

That’s pretty much all I wanted to say. Those two points took me a while to understand, so hope your found my post within your first hour of searching. 😅

©2024 Rail Yard Works LTD is registered in England and Wales, no. 12126621.