Skip to main content
Назад к блогу
5 мин чтения

Миграция с Tailwind 3 на Tailwind 4: путь за 90 минут

Я мигрировал проект на Next.js с 40 компонентами с Tailwind 3 на Tailwind 4 за 90 минут. Вот пошаговый процесс, что сломалось, что пропустил кодмод, и один подводный камень, который стоил мне 20 минут.

next.jsperformance

Tailwind 4 — значительная переработка: новый движок, CSS-first конфигурация, по умолчанию больше нет tailwind.config.js. Звучит страшно. На практике миграция реального проекта с 40 компонентами на Next.js заняла 90 минут. Большая часть была прямолинейной. Один подводный камень стоил мне 20 минут.

Вот точный путь.

Шаг 1: Запускаем кодмод (15 минут)

Tailwind предоставляет официальный инструмент обновления:

npx @tailwindcss/upgrade

Он берёт на себя основную часть миграции:

На моём проекте кодмод обработал около 85% изменений автоматически. Он модифицировал 28 файлов и файл глобальных стилей.

Важно: сделай коммит перед запуском кодмода, чтобы видеть точно, что он изменил, и откатиться при необходимости.

Шаг 2: Фиксим то, что кодмод пропустил (30 минут)

Кодмод хорош, но не идеален. Вот что пришлось исправить вручную:

Кастомные цвета в tailwind.config.js

В моём проекте кастомные цвета были определены через CSS custom properties:

// Было: tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        accent: 'var(--color-accent)',
        surface: 'var(--color-surface)',
      },
    },
  },
}

Кодмод перенёс это в CSS-файл, но синтаксис для ссылок на CSS-переменные изменился:

/* Стало: globals.css */
@theme {
  --color-accent: var(--color-accent);
  --color-surface: var(--color-surface);
}

Это создаёт циклическую ссылку. Исправление: используй в @theme реальные значения цветов, или определяй CSS-переменные отдельно и ссылайся на них:

:root {
  --color-accent: oklch(0.7 0.15 200);
  --color-surface: oklch(0.15 0.02 260);
}

@theme {
  --color-accent: var(--color-accent);
  --color-surface: var(--color-surface);
}

@apply с вариантами

Некоторые случаи использования @apply с вариантами потребовали ручной правки. Кодмод пропустил случаи, где @apply находился внутри медиа-запросов или псевдоселекторов.

Динамические имена классов

Если ты конструируешь имена классов динамически (шаблонные строки, условия clsx), кодмод не сможет их обнаружить. Пришлось вручную проверить компоненты, собирающие строки классов.

Шаг 3: Подводный камень — конфигурация content (20 минут)

Вот что стоило мне 20 минут. В Tailwind 3 ты конфигурируешь, какие файлы сканировать для поиска имён классов:

// tailwind.config.js
module.exports = {
  content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}'],
}

Tailwind 4 автоматически определяет источники контента — сканирует все файлы, импортированные из твоей точки входа CSS. Теоретически конфиг content не нужен.

На практике, если у тебя есть классы в файлах, которые напрямую не импортируются (например, MDX-контент или утилитарные файлы, не входящие в дерево импортов), Tailwind 4 их не найдёт, и стили не сгенерируются.

В моих MDX-постах блога кастомные компоненты используют классы Tailwind. Кодмод убрал конфиг content, и внезапно стили постов пропали. Исправление:

/* globals.css */
@source "../content/**/*.mdx";

Директива @source говорит Tailwind 4 сканировать дополнительные пути. Проверяй отрендеренные страницы после миграции — если стили пропали, скорее всего нужно добавить директиву @source.

Шаг 4: Верификация (25 минут)

После изменений кода:

  1. npm run build — проверь на ошибки компиляции. Tailwind 4 строже относится к некоторым паттернам классов.
  2. Визуальная проверка каждой страницы. Открой dev-сервер и кликай по всем страницам. Ищи:
    • Пропавшие цвета (не мигрировавшие значения кастомной темы)
    • Изменения в отступах (некоторые дефолтные значения слегка сдвинулись)
    • Изменения shadow/blur/ring (конвенция именования обновлена)
    • Проблемы с тёмной темой (если используешь стратегию class)
  3. Быстрая проверка Lighthouse. Новый движок Tailwind 4 генерирует меньший CSS. На моём проекте CSS-бандл упал с 28КБ до 19КБ (снижение на 32%). Оценка производительности Lighthouse выросла на 2 пункта.

Что реально стало лучше в Tailwind 4

Помимо самой миграции, вот почему обновление того стоит:

Быстрее билды. Новый движок Oxide написан на Rust. На моём проекте компиляция CSS упала с ~400мс до ~80мс. Заметно при перезапусках dev-сервера.

Меньше вывод. Новый движок агрессивнее удаляет неиспользуемые стили. По моему опыту — CSS меньше на 20–35%.

CSS-first конфиг. Определение темы в CSS (вместо JS) означает, что IDE может автодополнять кастомные значения и показывать превью. Петля обратной связи быстрее.

Нативные каскадные слои. Tailwind 4 нативно использует @layer, что означает лучшее взаимодействие с CSS третьих сторон и меньше проблем со специфичностью.

На что обратить внимание

Совместимость плагинов. Если используешь плагины Tailwind (typography, forms, container-queries), проверь, что у них есть версии, совместимые с Tailwind 4. API плагинов изменился.

tailwind.config.js всё ещё работает. Если у тебя сложная конфигурация (плагины, кастомные утилиты), можешь оставить JS-конфиг. Tailwind 4 поддерживает и CSS-first, и JS-конфигурацию. Миграция не обязана быть «всё или ничего».

Изменения PostCSS. Tailwind 4 использует собственный пайплайн PostCSS. Если у тебя есть кастомные плагины PostCSS, проверь, что они работают с новой настройкой.

Хронология

ШагВремя
Запуск кодмода15 мин
Исправление пропусков кодмода30 мин
Исправление конфига content/source20 мин
Визуальная верификация25 мин
Итого90 мин

Для более крупного проекта (100+ компонентов, серьёзная кастомизация) закладывай 2–3 часа. Для небольшого проекта (лендинг, портфолио) — 30–45 минут.

Миграция того стоит. Быстрые билды, меньше CSS, и именно Tailwind 4 — направление развития экосистемы. Чем дольше ждёшь, тем больше будет дифф.


Нужна помощь с миграцией проекта на Tailwind 4? Давай поговорим — я держу клиентские проекты на актуальном инструментарии, чтобы у них не накапливался технический долг.