Back to skills
SkillHub ClubShip Full StackFull Stack

migrating-from-v3

Imported from https://github.com/djankies/claude-configs.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
0
Hot score
74
Updated
March 20, 2026
Overall rating
C2.3
Composite score
2.3
Best-practice grade
A92.0

Install command

npx @skill-hub/cli install djankies-claude-configs-migrating-from-v3

Repository

djankies/claude-configs

Skill path: tailwind-4/skills/migrating-from-v3

Imported from https://github.com/djankies/claude-configs.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: djankies.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install migrating-from-v3 into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/djankies/claude-configs before adding migrating-from-v3 to shared team environments
  • Use migrating-from-v3 for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: migrating-from-v3
description: Migrate from Tailwind CSS v3 to v4 including configuration migration (JS to CSS), utility renames, opacity changes, and color system updates. Use when upgrading existing projects to v4.
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
---

# Migrating from v3 to v4

## Purpose

Migrate existing Tailwind CSS v3 projects to v4's CSS-first configuration, updated utilities, and modern color system.

## Automated Migration Tool

Tailwind provides an automated upgrade tool:

```bash
npx @tailwindcss/upgrade@next
```

**Requirements:**
- Node.js 20 or higher
- Run in a new git branch
- Review all changes manually
- Test thoroughly

**What it handles:**
- Updates dependencies
- Migrates configuration to CSS
- Updates template files
- Converts utility class names

**What it doesn't handle:**
- Custom plugins (manual migration needed)
- Complex configuration logic
- Dynamic class generation

## Configuration Migration

### JavaScript Config → CSS Theme

**v3 (tailwind.config.js):**

```javascript
module.exports = {
  content: ['./src/**/*.{html,js}'],
  theme: {
    extend: {
      colors: {
        brand: '#3b82f6',
        accent: '#a855f7',
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
        display: ['Satoshi', 'sans-serif'],
      },
      spacing: {
        18: '4.5rem',
        72: '18rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },
  plugins: [],
};
```

**v4 (CSS @theme):**

```css
@import 'tailwindcss';

@theme {
  --font-sans: 'Inter', sans-serif;
  --font-display: 'Satoshi', sans-serif;

  --color-brand: oklch(0.65 0.25 270);
  --color-accent: oklch(0.65 0.25 320);

  --spacing-18: 4.5rem;
  --spacing-72: 18rem;

  --radius-4xl: 2rem;
}
```

### Content Detection

**v3:**

```javascript
content: ['./src/**/*.{html,js,jsx,ts,tsx}']
```

**v4:**

Automatic detection. No configuration needed.

**Manual control (if needed):**

```css
@import 'tailwindcss';
@source "../packages/ui";
@source not "./legacy";
```

### Import Syntax Changes

**v3:**

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

**v4:**

```css
@import 'tailwindcss';
```

## Utility Class Renames

### Opacity Modifiers

**v3:**

```html
<div class="bg-black bg-opacity-50"></div>
<div class="text-gray-900 text-opacity-75"></div>
<div class="border-blue-500 border-opacity-60"></div>
```

**v4:**

```html
<div class="bg-black/50"></div>
<div class="text-gray-900/75"></div>
<div class="border-blue-500/60"></div>
```

**Migration pattern:**

- `bg-opacity-{value}` → `bg-{color}/{value}`
- `text-opacity-{value}` → `text-{color}/{value}`
- `border-opacity-{value}` → `border-{color}/{value}`

### Flex Utilities

**v3:**

```html
<div class="flex-shrink-0"></div>
<div class="flex-shrink"></div>
<div class="flex-grow-0"></div>
<div class="flex-grow"></div>
```

**v4:**

```html
<div class="shrink-0"></div>
<div class="shrink"></div>
<div class="grow-0"></div>
<div class="grow"></div>
```

**Migration pattern:**

- `flex-shrink-*` → `shrink-*`
- `flex-grow-*` → `grow-*`

### Shadow Utilities

**v3:**

```html
<div class="shadow-sm"></div>
```

**v4:**

```html
<div class="shadow-xs"></div>
```

**Migration:**

- `shadow-sm` → `shadow-xs`
- All other shadow utilities remain the same

### Ring Width

**v3 default:**

```html
<input class="ring" />
```

Ring width: 3px

**v4 default:**

```html
<input class="ring" />
```

Ring width: 1px

**To keep v3 behavior:**

```html
<input class="ring-3" />
```

## Color System Changes

### Default Border and Ring Colors

**v3:**

```html
<div class="border"></div>
```

Border color: gray-200

**v4:**

```html
<div class="border"></div>
```

Border color: currentColor

**To keep v3 behavior:**

```html
<div class="border border-gray-200"></div>
```

### OkLCh Color Space

**v3 (RGB):**

```javascript
colors: {
  brand: '#3b82f6',
}
```

**v4 (OkLCh):**

```css
@theme {
  --color-brand: oklch(0.65 0.25 270);
}
```

Use conversion tool: https://oklch.com/

## PostCSS Configuration

### Plugin Changes

**v3:**

```javascript
module.exports = {
  plugins: {
    'tailwindcss': {},
    'autoprefixer': {},
  },
};
```

**v4:**

```javascript
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};
```

No longer need `autoprefixer` or `postcss-import`.

### Vite Plugin

**v3:**

```javascript
import tailwindcss from 'tailwindcss';
import autoprefixer from 'autoprefixer';

export default defineConfig({
  css: {
    postcss: {
      plugins: [tailwindcss(), autoprefixer()],
    },
  },
});
```

**v4:**

```javascript
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [tailwindcss()],
});
```

## Preflight Changes

### Placeholder Colors

**v3:**

Placeholder text: gray-400

**v4:**

Placeholder text: currentColor at 50% opacity

**To keep v3 behavior:**

```css
@layer base {
  ::placeholder {
    color: theme('colors.gray.400');
  }
}
```

### Button Cursor

**v3:**

```css
button {
  cursor: pointer;
}
```

**v4:**

```css
button {
  cursor: default;
}
```

**To restore v3 behavior:**

```css
@layer base {
  button {
    cursor: pointer;
  }
}
```

## Feature Additions

### Built-in Container Queries

**v3 (plugin required):**

```javascript
plugins: [require('@tailwindcss/container-queries')]
```

**v4 (built-in):**

No plugin needed. Use `@container` and `@{breakpoint}:` syntax.

### 3D Transforms

**v3:**

Not available

**v4:**

```html
<div class="transform-3d rotate-x-45 rotate-y-30 translate-z-12"></div>
```

### Starting Variant for Animations

**v3:**

Not available

**v4:**

```html
<div class="opacity-100 starting:opacity-0 transition-opacity"></div>
```

## Breaking Changes Checklist

- [ ] Update dependencies to v4
- [ ] Migrate tailwind.config.js to @theme
- [ ] Replace @tailwind directives with @import
- [ ] Update PostCSS configuration
- [ ] Convert opacity utilities (bg-opacity → bg-{color}/{value})
- [ ] Rename flex utilities (flex-shrink → shrink)
- [ ] Update shadow-sm to shadow-xs
- [ ] Add explicit border colors if using bare `border`
- [ ] Update ring-3 if expecting 3px default
- [ ] Convert hex colors to oklch()
- [ ] Remove container-queries plugin (now built-in)
- [ ] Test placeholder colors
- [ ] Test button cursor behavior
- [ ] Update arbitrary value syntax (spaces → underscores)

## Migration Strategy

### Phase 1: Preparation

1. Create new git branch
2. Ensure all changes committed
3. Run automated migration tool
4. Review generated changes

### Phase 2: Configuration

1. Convert tailwind.config.js to CSS @theme
2. Update PostCSS/Vite configuration
3. Replace @tailwind directives
4. Add @source if needed

### Phase 3: Utilities

1. Search and replace opacity modifiers
2. Rename flex utilities
3. Update shadow utilities
4. Add explicit border colors
5. Convert hex colors to oklch()

### Phase 4: Testing

1. Test all pages/components
2. Verify responsive behavior
3. Check dark mode
4. Test interactive states
5. Validate production build

### Phase 5: Cleanup

1. Remove unused dependencies
2. Delete tailwind.config.js
3. Update documentation
4. Commit changes

## Common Issues

### Styles Not Applying

Check:
1. CSS import: `@import "tailwindcss";`
2. PostCSS plugin: `@tailwindcss/postcss`
3. Vite plugin: `@tailwindcss/vite`
4. Template files not in .gitignore

### Class Names Not Working

Ensure:
1. Class names are complete strings
2. Not using dynamic concatenation
3. Using underscores for spaces in arbitrary values

### Colors Look Different

OkLCh uses different color space. Convert hex to oklch using:
https://oklch.com/

### Build Errors

Check:
1. Node.js version (20+)
2. Dependencies updated
3. PostCSS config using correct plugin

## See Also

- references/breaking-changes.md - Complete breaking changes list
- references/migration-checklist.md - Step-by-step migration guide