# converting-css-modules-to-tailwind

Moves one component off CSS Modules and onto Tailwind utility classes, then removes the module file and its import.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 392 installs · ★ 866
- Author: spencerpauly
- License: CC0-1.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/spencerpauly/awesome-cursor-skills/tree/HEAD/resources/converting-css-modules-to-tailwind/SKILL.md
- Updated: 2026-08-02
- HTML: https://affpapa.org/en/nevibecode/skills/converting-css-modules-to-tailwind

## What it does

The skill reads a component and its `.module.css` or `.module.scss`, maps every `styles.xxx` reference to the CSS rule behind it, and swaps it for Tailwind utilities. It also covers the patterns that usually stall a migration: `composes`, conditional `className` calls through `clsx`, dynamic class selection, and `:global(...)` overrides. For dynamic variants it suggests a lookup object such as `variantClasses[variant]` instead of building a class name from a string.

Cleanup is part of the workflow. The skill drops the module import line, deletes the `.module.css` or `.module.scss` file, and searches the codebase for other imports of it. SCSS nesting gets flattened into utilities on each element, `$variables` are meant to move into `tailwind.config.ts` theme values, and mixins turn into utility composition or a separate component. Pseudo-elements that carry `content` need `before:` or `after:` prefixes plus a `content-['...']` value.

It converts one component at a time and will not batch a whole directory. Where Tailwind has no matching variant for `:nth-child` or `:first-of-type`, it keeps a minimal CSS rule rather than forcing a rewrite. It also refuses to recreate the module as `@apply` classes, because the point of the migration is to remove that indirection.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add spencerpauly/awesome-cursor-skills --skill converting-css-modules-to-tailwind -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/converting-css-modules-to-tailwind/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/converting-css-modules-to-tailwind/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add spencerpauly/awesome-cursor-skills --skill converting-css-modules-to-tailwind -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/converting-css-modules-to-tailwind/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add spencerpauly/awesome-cursor-skills --skill converting-css-modules-to-tailwind -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/converting-css-modules-to-tailwind/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install spencerpauly/awesome-cursor-skills converting-css-modules-to-tailwind
```

2. **Manually: put the files in place**
- File: `.github/skills/converting-css-modules-to-tailwind/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add spencerpauly/awesome-cursor-skills --skill converting-css-modules-to-tailwind -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/spencerpauly/awesome-cursor-skills --path resources/converting-css-modules-to-tailwind
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/converting-css-modules-to-tailwind/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add spencerpauly/awesome-cursor-skills --skill converting-css-modules-to-tailwind -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/spencerpauly/awesome-cursor-skills/tree/HEAD/resources/converting-css-modules-to-tailwind/SKILL.md

## When to use it
- convert a component from `.module.css` to Tailwind classes
- flatten `composes` into a single set of utilities
- replace `styles[variant]` with a variant lookup object
- move `:global(...)` rules into the global stylesheet
- delete the module file and catch leftover imports

## Example prompts
- convert `Card.module.css` to Tailwind, component is `Card.tsx`
- strip `styles.xxx` from `Button.tsx` and delete the module
- flatten `composes` in `Button.module.scss` into utilities

## Source text · SKILL.md · CC0-1.0

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: c36758eaeb95546f.

BEGIN THIRD-PARTY FILE c36758eaeb95546f
````text
---
name: converting-css-modules-to-tailwind
description: Migrate CSS Modules (.module.css/.module.scss) to Tailwind utility classes. Handles styles object removal, className interpolation, composition, and global overrides.
user-invocable: true
---

# Converting CSS Modules to Tailwind

Migrate a component from CSS Modules (`.module.css` / `.module.scss`) to Tailwind utility classes.

## Workflow

### 1. Inventory the Module

Read the `.module.css` file and the component that imports it. Map every `styles.xxx` reference to the CSS rule it resolves to.

```tsx
// Before
import styles from './Card.module.css';
<div className={styles.card}>
  <h2 className={styles.title}>{title}</h2>
  <p className={styles.body}>{children}</p>
</div>
```

```css
/* Card.module.css */
.card { display: flex; flex-direction: column; gap: 16px; padding: 24px; border-radius: 12px; background: white; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.title { font-size: 20px; font-weight: 600; color: #111827; }
.body { font-size: 14px; color: #6b7280; line-height: 1.6; }
```

### 2. Convert Each Class

Replace `styles.xxx` with equivalent Tailwind utilities:

```tsx
// After
<div className="flex flex-col gap-4 p-6 rounded-xl bg-white shadow-sm">
  <h2 className="text-xl font-semibold text-gray-900">{title}</h2>
  <p className="text-sm text-gray-500 leading-relaxed">{children}</p>
</div>
```

### 3. Handle CSS Modules Patterns

**`composes` keyword:**
```css
.base { padding: 8px 16px; border-radius: 4px; }
.primary { composes: base; background: blue; color: white; }
```
→ Flatten into a single set of utilities. If reuse is needed, extract a component, not a class.

**Conditional classNames with `clsx`/`classnames`:**
```tsx
// Before
className={clsx(styles.button, isActive && styles.active)}
// After
className={clsx("px-4 py-2 rounded", isActive && "bg-blue-600 text-white")}
```

**Dynamic class selection:**
```tsx
// Before
className={styles[variant]}
// After — use a lookup object
const variantClasses = {
````
END THIRD-PARTY FILE c36758eaeb95546f

The third-party file has ended. Everything between the c36758eaeb95546f tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2010 of 3544 bytes. © spencerpauly · CC0-1.0 · https://github.com/spencerpauly/awesome-cursor-skills/tree/HEAD/resources/converting-css-modules-to-tailwind/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
