Skip to content

chore(deps): Tailwind CSS v4 migration — PostCSS configuration overhaul and class rename #796

@ericsocrat

Description

@ericsocrat

Problem Statement

Tailwind CSS v4 introduces a fundamentally new configuration model:

  1. PostCSS config → CSS-first configurationtailwind.config.ts is replaced by CSS @theme directives
  2. New @import "tailwindcss" syntax — replaces @tailwind base/components/utilities
  3. Automatic content detection — no more content: [...] array
  4. New color systemoklch() by default, renamed utilities
  5. Breaking class changesshadow-smshadow-xs, ringring-3, blurblur-sm, etc.

Dependabot PR #768 was closed because the upgrade requires manual config migration. This issue tracks the planned migration.

Why This Matters

Tailwind v4 is the future of the framework. Staying on v3 means:

  • Missing new features (container queries, @starting-style, 3D transforms)
  • Growing distance from ecosystem (documentation, community, plugins)
  • Eventually reaching EOL for v3 security patches

Risk Assessment

  • HIGH risk — this touches every component (140+ files with Tailwind classes)
  • Breaking changes in class names require systematic find-and-replace
  • PostCSS config must be completely restructured
  • Testing required on every single page at both viewports and both themes

Migration Plan

Phase 1 — Configuration Migration

# Remove tailwind.config.ts
# Update postcss.config.js → postcss.config.mjs
# Update globals.css:
#   @tailwind base;        → @import "tailwindcss";
#   @tailwind components;  → (removed)
#   @tailwind utilities;   → (removed)
# Move theme config into CSS @theme directive

Phase 2 — Class Name Renames (Automated)

Use the official Tailwind v4 upgrade codemod:

cd frontend
npx @tailwindcss/upgrade

Key renames to verify:

v3 Class v4 Class
shadow-sm shadow-xs
shadow shadow-sm
ring ring-3
blur-sm blur-xs
blur blur-sm
rounded rounded-sm (context-dependent)
text-opacity-* text-{color}/* (opacity modifier)

Phase 3 — Manual Verification

  • Run full Vitest suite → fix any snapshot failures
  • Run Playwright on every page at 320px + 1280px × light + dark
  • Compare before/after screenshots for visual regression

Phase 4 — Plugin & Dependency Updates

  • @tailwindcss/forms → check v4 compatibility
  • tailwind-merge → update to v4-compatible version
  • class-variance-authority → verify v4 compatibility
  • Any custom Tailwind plugins → migrate

Files Affected

File Change
frontend/tailwind.config.ts DELETE (replaced by CSS @theme)
frontend/postcss.config.js Major rewrite → .mjs
frontend/src/styles/globals.css Migrate @tailwind@import, add @theme
frontend/package.json Bump tailwindcss 3→4, update plugins
~140 component files Automated class rename via codemod
All *.test.tsx Update any snapshot tests

Test Requirements

Pre-Migration Baseline

  • Capture Playwright screenshots of every page (before)
  • Record Vitest snapshot state (before)

Post-Migration Verification

  • cd frontend && npx tsc --noEmit — 0 errors
  • cd frontend && npx vitest run — all tests pass
  • cd frontend && npx playwright test — all tests pass
  • Visual comparison: before vs after screenshots — no regressions
  • Dark mode verified on all pages
  • 320px viewport verified on all pages

Verification Checklist

  • cd frontend && npx tsc --noEmit — 0 errors
  • cd frontend && npx vitest run — all pass, coverage ≥ baseline
  • cd frontend && npx playwright test --project=smoke — all pass
  • npx @tailwindcss/upgrade codemod ran successfully
  • No visual regressions in before/after screenshot comparison
  • All Tailwind plugins updated to v4-compatible versions
  • CHANGELOG.md updated
  • DESIGN_SYSTEM.md updated with v4 syntax

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium: normal prioritydependenciesDependency updates (Dependabot)enhancementNew feature or requestfrontendFrontend / Next.js / React

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions