Tailwind v4: что изменилось и как мигрировать
Tailwind v4 — это переписанная версия фреймворка, которая выглядит так же, как и третья (на 95% те же классы), но внутри устроена иначе. Я закончила миграцию двух проектов с v3 на v4. Для одного — это быстро и приятно, для второго — потребовался день работы. Расскажу, что реально меняется и где готовить себя к копаниям.
Что под капотом
Главное архитектурное изменение: Tailwind v4 написан с нуля на Rust-подобной механике с движком Lightning CSS. Сборка стала в среднем в три-десять раз быстрее. У меня на проекте с 1500 файлов JSX полная пересборка стилей упала с 2,1 секунды до 220 мс. Это заметно даже в обычной работе с HMR.
Второй фундаментальный момент — конфиг переехал из JS-файла в CSS. Раньше у нас был tailwind.config.ts, теперь конфиг лежит прямо в твоём главном CSS-файле через директивы @theme и @source. Это сначала непривычно, но через пару дней понимаешь, что так логичнее.
Установка
В новых проектах:
pnpm add -D tailwindcss@latest @tailwindcss/postcss@latestВ postcss.config.mjs:
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};Главный CSS:
@import 'tailwindcss';
@theme {
--color-brand: oklch(67% 0.2 150);
--font-display: 'Inter', sans-serif;
}
@source './src/**/*.{tsx,astro,html}';Это всё. Никакого content-массива, никакого theme.extend. Сами переменные становятся именами классов: bg-brand, font-display.
Миграция: codemod есть, но осторожно
Команда выпустила @tailwindcss/upgrade:
pnpm dlx @tailwindcss/upgrade@latestУтилита подхватывает tailwind.config.js/ts, переписывает токены в CSS, обновляет директивы и заодно меняет устаревшие классы на новые. На простом проекте всё работает из коробки. На сложном — codemod честно скажет, что нашёл места, в которые не полез: кастомные плагины, JS-логика темизации, нестандартные конфигурации safelist.
На втором проекте у нас были кастомные плагины tailwindcss-animate и собственный плагин для типографики. Они работают и в v4, но загружать их надо иначе — через @plugin в CSS:
@import 'tailwindcss';
@plugin 'tailwindcss-animate';
@plugin '../plugins/typography.js';Удалённые и переименованные утилиты
Часть классов удалили или переименовали. Самое массовое:
shadow-smтеперьshadow-xs;shadow— этоshadow-smпо новой шкале.rounded-smтеперьrounded-xs, всё на размер.opacity-95и подобные мелкие шаги дёрнулись по шкалам, проверь руками.bg-opacity-X,text-opacity-Xи им подобные — удалены, используй цветовые модификаторы:bg-blue-500/50.flex-shrink-0переименовано вshrink-0;flex-grow-0— вgrow-0. Старые имена не работают.
Codemod ловит большую часть переименований, но не все. После запуска прогон по проекту обязательное.
Темизация — это CSS
Главное концептуальное отличие. Раньше:
// tailwind.config.ts (v3)
export default {
theme: {
extend: {
colors: { brand: 'rgb(var(--brand) / <alpha-value>)' },
},
},
};Теперь:
/* main.css (v4) */
@import 'tailwindcss';
@theme {
--color-brand: oklch(67% 0.2 150);
--color-brand-soft: color-mix(in oklch, var(--color-brand) 30%, white);
--spacing-section: 6rem;
}Каждое имя переменной становится классом. --color-brand → bg-brand, text-brand, border-brand. --spacing-section → p-section, my-section. Это не магия: Tailwind просто читает :root-переменные и из их имён строит классы.
На больших дизайн-системах удобно — вся палитра в одном месте, и она автоматически доступна как переменные CSS для рантайм-стилизации.
Тёмная тема
В v4 поведение dark: по умолчанию завязано на media-запрос (prefers-color-scheme). Если хочешь класс html.dark — нужно явно настроить:
@import 'tailwindcss';
@variant dark (&:where(.dark, .dark *));И токены для тёмной темы — через :root.dark:
:root.dark {
--color-bg: #0e0e10;
--color-fg: #f5f5f7;
}Custom variants — проще
В v3 кастомные варианты делались через JS-плагин. В v4 — через @variant в CSS:
@variant hocus (&:hover, &:focus-visible);И теперь в JSX можно писать hocus:bg-brand. Это здорово сокращает количество JS-плагинов в проектах.
Проблемы, которые я ловила
Цвета через прозрачность. У нас был привычный паттерн bg-black/50 — он работает. А вот bg-black bg-opacity-50 — нет: bg-opacity-X удалили, и это вызывает молчаливый отказ. Codemod подхватывает не все случаи, ищи opacity-классы вручную.
Контейнеры. Класс container в v3 имел особое поведение через theme.container. В v4 этого нет — просто пиши max-w-7xl mx-auto px-4 или сделай свой компонент.
Шрифты. Если ты раньше писал fontFamily.sans в конфиге, теперь это переменная --font-sans в @theme. Codemod это переносит, но если используется next/font — нужно прокинуть переменную в html и связать её с --font-sans.
Производительность сборки
Самое заметное улучшение — скорость. Это не маркетинг, это реальные миллисекунды на каждом сохранении файла. На большом проекте с дизайн-системой я раньше ждала пересборки несколько секунд после правки токена; теперь — мгновенно. Hot reload в dev-сервере чувствуется мгновенным.
Браузеры
Tailwind v4 опирается на современные CSS-фичи: @property, color-mix(), cascade layers. Минимальные требования — Chromium 111+, Safari 16.4+, Firefox 128+. На старых браузерах стили могут отрисовываться нестабильно. Если в твоей аудитории есть пользователи на Chromium 108 — это блокер. Если все на актуальных версиях — без проблем.
Стоит ли переходить
Если проект новый — однозначно, без вариантов. Если старый — оцени, насколько у тебя кастомизированы плагины и темы. На простой админке миграция — час. На дизайн-системе с своими плагинами и темами — день, иногда два.
Куда копать дальше
Когда базовая миграция закончена, попробуй переписать кастомные компоненты, которые ты раньше делал через @apply. В v4 этот паттерн допустим, но коммьюнити постепенно склоняется к чистым CSS-переменным и компонентам без @apply. Это даёт лучшую производительность и более прозрачный CSS.