CSS Modules
Automatic local scoping system for CSS that prevents naming conflicts by generating unique class names per component.
Updated on January 22, 2026
CSS Modules is a styling approach that solves the global scope problem in CSS by automatically transforming class names into unique identifiers. This technique guarantees style isolation per component, eliminating naming conflicts and facilitating maintenance of complex applications. Widely adopted in the React, Next.js, and Vue.js ecosystems, CSS Modules combines the benefits of traditional CSS with the modularity of modern development.
Fundamentals
- Automatic generation of unique class names via cryptographic hashing
- Local scope by default with explicit global declarations when needed
- Style composition enabling reusability through @value and composes
- Native integration in modern bundlers (Webpack, Vite, Turbopack)
Benefits
- Complete elimination of class name conflicts between components
- Optional type safety through TypeScript definition generation
- Automatic CSS optimization with tree-shaking of unused styles
- Enhanced maintainability through style colocation with components
- Optimal performance without JavaScript runtime unlike CSS-in-JS
Practical Example
/* Local styles by default */
.button {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-weight: 600;
transition: all 0.2s;
}
.primary {
composes: button;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.secondary {
composes: button;
background: transparent;
border: 2px solid #667eea;
color: #667eea;
}
/* Explicit global declaration */
:global(.theme-dark) .button {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}import React from 'react';
import styles from './Button.module.css';
interface ButtonProps {
variant?: 'primary' | 'secondary';
children: React.ReactNode;
onClick?: () => void;
}
export const Button: React.FC<ButtonProps> = ({
variant = 'primary',
children,
onClick
}) => {
return (
<button
className={styles[variant]}
onClick={onClick}
>
{children}
</button>
);
};
// Generated classes: Button_primary__xJ8k2, Button_secondary__9mL4pImplementation
- Install required dependencies: css-loader for Webpack or native configuration for Next.js/Vite
- Create CSS files with .module.css or .module.scss extension for automatic activation
- Import styles as JavaScript object: import styles from './Component.module.css'
- Apply classes via styles.className to benefit from local scope
- Configure TypeScript with typed-css-modules to generate type definitions
- Use :global() for rare cases requiring explicit global scope
Advanced Optimization
Combine CSS Modules with CSS custom properties to create a maintainable design token system. Use @value to share constants between module files, and enable cssModules.localsConvention: 'camelCase' for TypeScript-friendly access (styles.primaryButton instead of styles['primary-button']).
Related Tools
- PostCSS: advanced processing with plugins for autoprefixer and optimizations
- typed-css-modules: automatic TypeScript definition generation
- clsx / classnames: libraries for conditional class composition
- CSS Modules Values: extension for shared variables between modules
- Webpack css-loader: reference loader with extended configuration options
- Vite: native support without configuration for CSS/SCSS Modules
CSS Modules represents a mature and performant solution for CSS architecture in modern applications. By offering isolation by default without sacrificing performance or the familiarity of standard CSS, this approach significantly reduces styling-related bugs while improving team velocity. For enterprises seeking a balance between modernity and pragmatism, CSS Modules constitutes a sustainable strategic choice, compatible with all major frameworks and benefiting from a robust tool ecosystem.
