Tailwind 4 — це суттєва переробка: новий рушій, CSS-first конфігурація, за замовчуванням більше немає tailwind.config.js. Звучить страшно. На практиці міграція реального проєкту з 40 компонентів зайняла 90 хвилин. Більшість — прямолінійно. Один підводний камінь коштував 20 хвилин.
Ось точний шлях.
Крок 1: Запусти codemod (15 хвилин)
Tailwind надає офіційний інструмент для апгрейду:
npx @tailwindcss/upgrade
Він бере на себе основну частину міграції:
- Переносить конфіг із
tailwind.config.jsдо CSS (директиви@themeу твоєму глобальному CSS-файлі) - Оновлює назви класів, що змінились (наприклад,
shadow-sm→shadow-xs,blur-sm→blur-xs) - Конвертує директиви
@applyна новий синтаксис там, де потрібно - Оновлює конфіг PostCSS
На моєму проєкті codemod автоматично обробив ~85% змін. Він змінив 28 файлів і глобальний CSS-файл.
Важливо: зроби коміт перед запуском codemod, щоб бачити точно, що він змінив, і мати можливість відкотитись.
Крок 2: Виправ те, що пропустив codemod (30 хвилин)
Codemod хороший, але не ідеальний. Ось що довелось виправляти вручну:
Кастомні кольори в tailwind.config.js
У моєму проєкті були кастомні кольори, визначені через CSS custom properties:
// Раніше: tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
accent: 'var(--color-accent)',
surface: 'var(--color-surface)',
},
},
},
}
Codemod переніс це в 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 із варіантами потребувала ручного виправлення. Codemod пропустив випадки, де @apply був усередині media query або pseudo-селекторів.
Динамічні назви класів
Якщо ти будуєш назви класів динамічно (template literals, умови clsx), codemod не може їх виявити. Довелось вручну перевіряти компоненти, що збирають рядки класів.
Крок 3: Підводний камінь — конфігурація content (20 хвилин)
Ось що коштувало мені 20 хвилин. У Tailwind 3 ти конфігуруєш, які файли сканувати на назви класів:
// tailwind.config.js
module.exports = {
content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}'],
}
Tailwind 4 автоматично визначає джерела контенту — сканує всі файли, імпортовані з точки входу CSS. Теоретично конфіг content більше не потрібен.
На практиці, якщо у тебе є класи у файлах, які не імпортуються напряму (наприклад, MDX-контент або utility-файли, яких нема в дереві імпортів), Tailwind 4 їх не знайде і ці стилі не згенерує.
У моїх MDX-постах блогу кастомні компоненти використовують Tailwind-класи. Codemod видалив конфіг content, і раптово стилі постів зникли. Фікс:
/* globals.css */
@source "../content/**/*.mdx";
Директива @source каже Tailwind 4 сканувати додаткові шляхи. Після міграції перевіряй відрендерені сторінки — якщо стилі зникли, швидше за все потрібно додати директиву @source.
Крок 4: Верифікація (25 хвилин)
Після змін у коді:
npm run build— перевір на помилки компіляції. Tailwind 4 строгіший щодо деяких патернів класів.- Візуальна перевірка кожної сторінки. Відкрий dev server і пройдись по всіх сторінках. Шукай:
- Відсутні кольори (кастомні значення теми, що не мігрували)
- Зміни відступів (деякі дефолтні значення трохи зсунулись)
- Зміни shadow/blur/ring (оновлені конвенції іменування)
- Проблеми з dark mode (якщо використовуєш стратегію
class)
- Швидка перевірка Lighthouse. Новий рушій Tailwind 4 генерує менший CSS. На моєму проєкті CSS-бандл скоротився з 28 КБ до 19 КБ (32% зменшення). Показник Lighthouse performance виріс на 2 пункти.
Що реально краще в Tailwind 4
Окрім міграції — ось чому апгрейд вартий уваги:
Швидші білди. Новий рушій Oxide написаний на Rust. На моєму проєкті компіляція CSS пішла з ~400 мс до ~80 мс. Помітно під час перезапусків dev server.
Менший вивід. Новий рушій агресивніше видаляє невикористані стилі. 20–35% менший CSS на моєму досвіді.
CSS-first конфіг. Визначення теми в CSS (замість JS) означає, що IDE може автодоповнювати кастомні значення і показувати прев'ю. Цикл зворотного зв'язку швидший.
Нативні cascade layers. Tailwind 4 нативно використовує @layer, що означає кращу взаємодію зі стороннім CSS і менше проблем зі specificity.
На що звертати увагу
Сумісність плагінів. Якщо використовуєш Tailwind-плагіни (typography, forms, container-queries), перевір, що вони мають версії, сумісні з Tailwind 4. Plugin API змінився.
tailwind.config.js досі працює. Якщо у тебе складний конфіг (плагіни, кастомні утиліти), можеш залишити JS-конфіг. Tailwind 4 підтримує і CSS-first, і JS-конфіг. Міграція не мусить бути все-або-нічого.
Зміни PostCSS. Tailwind 4 використовує власний PostCSS pipeline. Якщо маєш кастомні PostCSS-плагіни, перевір, що вони досі працюють із новим setup-ом.
Таймлайн
| Крок | Час |
|---|---|
| Запустити codemod | 15 хв |
| Виправити пропуски codemod | 30 хв |
| Виправити конфіг content/source | 20 хв |
| Візуальна верифікація | 25 хв |
| Разом | 90 хв |
Для більшого проєкту (100+ компонентів, важка кастомізація) закладай 2–3 години. Для маленького проєкту (лендинг, портфоліо) — 30–45 хвилин.
Міграція варта уваги. Швидші білди, менший CSS, і Tailwind 4 — це напрямок, куди рухається екосистема. Чим довше чекаєш, тим більший diff.
Потрібна допомога з міграцією проєкту на Tailwind 4? Пиши — я тримаю клієнтські проєкти на актуальному інструментарії, щоб вони не накопичували технічний борг.