Как мигрировать проект с Tailwind v3 на v4 CSS-first configuration?
Миграция с v3 на v4: заменить tailwind.config.js на @import "tailwindcss" в CSS, перенести кастомные токены в @theme {}, обновить PostCSS-плагин до @tailwindcss/postcss и проверить изменившиеся классы (shadow, blur, ring и др.).
Миграция с Tailwind v3 на v4: CSS-first конфигурация
Tailwind v4 полностью отказался от JS-конфига в пользу нативного CSS. Миграция включает несколько обязательных шагов.
Шаг 1: Обновление зависимостей
// package.json — новые пакеты
// было: tailwindcss, postcss, autoprefixer
// стало:
{
"devDependencies": {
"tailwindcss": "^4.0.0",
"@tailwindcss/postcss": "^4.0.0"
}
}
// postcss.config.js
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
},
};
Отдельный autoprefixer больше не нужен — Tailwind v4 встраивает prefixing самостоятельно.
Шаг 2: Замена конфигурационного файла
Файл tailwind.config.js удаляется. Вся конфигурация переезжает в CSS:
/* было: @tailwind base; @tailwind components; @tailwind utilities; */
/* стало: */
@import "tailwindcss";
/* Кастомные токены — замена theme.extend */
@theme {
--color-brand: #6366f1;
--color-surface: #f8f9fa;
--font-sans: 'Inter', sans-serif;
--radius-card: 0.75rem;
--spacing-section: 4rem;
}
/* Подключение внешних источников классов */
@source "../node_modules/@myorg/ui/src/**/*.{js,ts,jsx,tsx}";
Шаг 3: Перенос theme.extend
В v3 кастомные значения добавлялись через theme.extend в JS. В v4 каждый токен становится CSS-переменной в блоке @theme:
// v3 tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: { 500: '#6366f1', 600: '#4f46e5' },
},
borderRadius: {
xl2: '1rem',
},
},
},
};
/* v4 — эквивалент в CSS */
@theme {
--color-primary-500: #6366f1;
--color-primary-600: #4f46e5;
--radius-xl2: 1rem;
}
Шаг 4: Изменившиеся утилиты
Ряд классов изменил поведение или переименован:
shadow→ теперьshadow-smпо умолчанию немного другой (проверить визуально);ringтеперьring-1по умолчанию (былоring-3);blur→blur-smизменил значение;outline-noneтеперь также устанавливаетoutline-offset: 0;- Цветовая палитра расширена,
slate/gray/zincслегка скорректированы.
Шаг 5: Использование официального codemoda
npx @tailwindcss/upgrade@next
Скрипт обновляет package.json, postcss.config.js, генерирует CSS-конфиг и пытается перевести tailwind.config.js. После запуска обязательно проверить diff вручную.
Шаг 6: Плагины
Плагины v3 (typography, forms, aspect-ratio) имеют v4-совместимые версии:
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";
Подводные камни
- Забытый
@sourceдля компонентных библиотек вnode_modules— классы вырезаются в продакшне. - Нельзя смешивать
tailwind.config.jsи@theme— v4 игнорирует JS-конфиг по умолчанию. - Изменённые дефолтные значения
ringиshadowломают существующий UI без явных ошибок. autoprefixerвpostcss.config.jsконфликтует с v4 — его нужно убрать.- Кастомные PostCSS-плагины могут не работать с новым порядком обработки.
- Vite требует
@tailwindcss/viteвместо PostCSS-плагина для лучшей производительности. - JIT-режим теперь единственный — нет fallback на полную сборку, несовместимые паттерны просто не работают.
- Тёмная тема через
darkMode: 'class'теперь настраивается через@variant dark (...)в CSS.
Common mistakes
- Отвечать определением без production-сценария.
- Не называть runtime boundary, security boundary или failure mode.
- Игнорировать версию API, observability и тестовую проверку.
What the interviewer is testing
- Объясняет механизм своими словами и без выдуманных API.
- Называет реальные риски, диагностику и критерий корректности.
- Связывает ответ с текущей документацией и миграционными ограничениями.