CSS Modules vs. Tailwind: A Valentine's Day Breakup Analysis
Some devs love Tailwind unconditionally. Others swear by CSS Modules. I've used both in production. Here's an honest post-Valentine's breakup analysis of which one you should actually commit to.
This debate has generated more hot takes than it deserves. Both CSS Modules and Tailwind are good tools. The question is which one fits your situation.
What CSS Modules actually give you
CSS Modules scope styles to the component by default. No global conflicts, no specificity wars. You write normal CSS — selectors, custom properties, media queries, the full language — and the build tool scopes it automatically.
/* Button.module.css */
.button {
background: var(--color-primary);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
}
.button:hover {
background: var(--color-primary-dark);
}
The component imports it:
import styles from "./Button.module.css";
export function Button({ children }) {
return <button className={styles.button}>{children}</button>;
}
Clean, explicit, colocated. The CSS lives next to the component. Design tokens live in custom properties. The mental model maps to the language.
What Tailwind actually gives you
Tailwind gives you a utility class for (almost) every CSS property. You compose styles directly in JSX:
export function Button({ children }) {
return (
<button className="bg-primary px-4 py-2 rounded-md hover:bg-primary-dark">
{children}
</button>
);
}
The win is speed: no context switching to a CSS file, no naming classes, no worrying about whether you've already written this style somewhere. The constraint is that your design tokens need to be in tailwind.config — if they're not configured, you reach for arbitrary values (bg-[#3b5bdb]) which undermines the whole system.
The real tradeoffs
Tailwind excels when:
- The team is familiar with it (there's a real learning curve)
- You're using a component library that's built with it (like shadcn/ui)
- Design-to-code velocity is the priority
- You have a designer who works in terms of spacing/color scales
CSS Modules excel when:
- The codebase already has a CSS custom property system
- You want full CSS expressiveness (complex animations, selectors, container queries)
- You're building for long-term readability — CSS is less likely to be cryptic to a developer who hasn't used Tailwind
The honest answer: On a solo project or small team with Tailwind experience, Tailwind is faster. On a larger codebase or with a team that has mixed CSS expertise, CSS Modules with a design token system is easier to maintain long-term.
I've shipped production code with both. Neither has made a project succeed or fail. Pick the one your team will actually use consistently.