Skip to content

πŸ’…πŸΎ A demonstration of different ways to style React components using CSS Modules, TailwindCSS, and Styled Components

Notifications You must be signed in to change notification settings

breehall/three-ways-to-style

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Three Ways to Style

This repository demonstrates different approaches to styling React components, including CSS Modules, Styled Components, and Tailwind CSS. Each implementation shows how to create and style a simple button component using these different methodologies.

Project Structure

β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ layout.tsx          # Root layout component
β”‚   β”œβ”€β”€ page.tsx            # Main page component
β”‚   β”œβ”€β”€ globals.css         # Global styles
β”‚   └── registry.tsx        # Styled-components registry
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ css-modules/        # CSS Modules implementation
β”‚   β”‚   β”œβ”€β”€ button.tsx
β”‚   β”‚   └── button.module.css
β”‚   β”œβ”€β”€ styled-components/  # Styled-components implementation
β”‚   β”‚   └── button.tsx
β”‚   └── tailwind/           # Tailwind CSS implementation
β”‚       └── button.tsx
└── styles/
    └── styled.d.ts         # Styled-components TypeScript definitions

Getting Started

  1. Clone the repository:
git clone https://github.com/breehall/three-ways-to-style
  1. Install dependencies:
npm install
  1. Run the development server:
npm run dev
  1. Open http://localhost:3000 in your browser to see the fancy buttons in action.

Styling Solutions

1. CSS Modules

CSS Modules allow you to write traditional CSS with locally scoped class names. This prevents style conflicts and provides better CSS organization.

Example usage:

import styles from './button.module.css';

const Button = ({
  variant,
  size,
  disabled,
  loading,
  icon,
  children,
  onClick,
}: ButtonProps) => {
  return <button className={styles.button}>{children}</button>;
};

2. Styled Components

Styled Components provide a way to write CSS-in-JS with a component-based approach. This allows for more dynamic and reusable styles.

Example usage:

import styled from 'styled-components';

const StyledButton = styled.button`
  background-color: ${({ theme }) => theme.colors.primary};
  color: ${({ theme }) => theme.colors.text};

3. Tailwind CSS

Tailwind CSS is a utility-first CSS framework that allows you to build complex designs with a minimal amount of code.

Example usage:

import { Button } from '@/components/tailwind/button';

export function Button() {
  return (
    <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
      Click me
    </button>
  );
}

πŸ” Key Benefits & Trade-offs

Here’s a quick breakdown of the pros and cons for each styling solution used in this repo:


🧩 CSS Modules

βœ… Pros

  • Simple, scoped styles with zero runtime
  • Familiar for developers coming from traditional CSS
  • SSR and React Server Component–friendly by default
  • No extra dependencies or config needed

⚠️ Trade-offs

  • No built-in support for variants or themes
  • Can get messy as components grow
  • Requires extra tooling or patterns to scale
  • Styling dynamic states can feel verbose or repetitive

πŸŽ€ Tailwind CSS + tailwind-variants

βœ… Pros

  • Utility-first styling = fast prototyping and predictable output
  • Scales well for large teams and design systems
  • tailwind-variants makes managing variants clean and composable
  • Supports theming via @theme and native CSS variables in v4
  • Minimal runtime, great performance

⚠️ Trade-offs

  • Readability can suffer with long class lists
  • Requires strong conventions to stay maintainable
  • Custom theming in CSS can get messy without structure
  • Learning curve for new team members unfamiliar with utility-first CSS

πŸ’… Styled Components

βœ… Pros

  • Dynamic styles based on props
  • Built-in theming via ThemeProvider
  • Highly expressive and colocated with component logic
  • Great for deeply interactive or animated components

⚠️ Trade-offs

  • Runtime style injection = performance cost
  • Not compatible with React Server Components (relies on context)
  • Hydration risks in SSR setups (like Next.js)
  • Officially in maintenance mode β€” alternatives like Emotion or vanilla-extract may be better for new projects

About This Repo

This repo was created for my talk at React Miami 2025 β€” β€œStyled & SASSy: Choosing the Right Styling Solution in React.”

In this talk, I walk through how the styling landscape is shifting with React 19, Tailwind v4, and modern CSS and how three popular approaches hold up: CSS Modules, Tailwind CSS, and Styled Components.

I’m Bree Hall, a software engineer, developer advocate, and your tech bestie ✨
I love helping devs make smarter styling decisions and build beautiful things with confidence.

πŸ‘‰ If you found this helpful, follow me for more styling tips, dev resources, and cozy frontend content 😊!

TikTok X Instagram YouTube

About

πŸ’…πŸΎ A demonstration of different ways to style React components using CSS Modules, TailwindCSS, and Styled Components

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy