Импортозамещение Emotion: пошаговая инструкция с нуля на примере Vanilla Extract

Подробное практическое руководство по замене библиотеки Emotion на отечественную альтернативу Vanilla Extract. Статья содержит пошаговую инструкцию: от оценки проекта и настройки сборки до создания стилей, работы с темами, динамическими пропсами и полной миграции. Объясняются преимущества подхода, его отличия от Emotion и стратегия постепенного внедрения.
Библиотека Emotion долгое время была одним из лидеров в мире CSS-in-JS для React-приложений, предлагая мощный API и высокую гибкость. Однако в контексте импортозамещения и желания снизить зависимость от зарубежных решений, многие команды ищут альтернативы. Одной из самых перспективных и современной является Vanilla Extract — CSS-инструментарий, который компилируется в статические CSS-классы, предлагая типобезопасность и отличную производительность. Давайте разберем пошаговый процесс миграции с Emotion на Vanilla Extract с нуля.

Шаг 1: Оценка и подготовка. Прежде всего, проанализируйте вашу кодовую базу. Определите, какие возможности Emotion вы используете активно: динамические стили на основе пропсов? Глобальные стили? Темызирование? Ключевые вставки (keyframes)? Vanilla Extract поддерживает большинство из этих концепций, но иначе. Создайте новый branch в вашем репозитории для экспериментов. Убедитесь, что ваш проект использует современный сборщик (Vite, Webpack 5) или фреймворк (Next.js 12+), так как Vanilla Extract требует настройки препроцессинга.

Шаг 2: Установка и базовая настройка. Установите необходимые пакеты. Для проекта на Vite это будет выглядеть так:
npm install @vanilla-extract/css @vanilla-extract/vite-plugin
Далее, нужно сконфигурировать плагин в `vite.config.ts`:
import { defineConfig } from 'vite';
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
export default defineConfig({
 plugins: [vanillaExtractPlugin()]
});
Для Next.js используется `@vanilla-extract/next-plugin`, для Webpack – свой плагин. После установки плагина, система сборки начнет обрабатывать файлы с расширением `.css.ts`.

Шаг 3: Создание первых стилей. В Emotion вы создавали стили с помощью `css` prop или `styled` компонентов. В Vanilla Extract вы создаете отдельный файл, например, `Button.css.ts`. Внутри него вы определяете стили с помощью функции `style`:
import { style } from '@vanilla-extract/css';
export const button = style({
 padding: '12px 24px',
 backgroundColor: 'blue',
 color: 'white',
 borderRadius: '8px',
});
Этот код скомпилируется в статический CSS-класс (что-то вроде `.button_sha256`). В вашем React-компоненте импортируйте этот класс и применяйте его:
import { button } from './Button.css.ts';
function MyButton() {
 return Click me;
}
Это основа. Вы уже получили типобезопасность – попытка указать несуществующее CSS-свойство вызовет ошибку TypeScript.

Шаг 4: Работа с динамическими пропсами и темами. Emotion позволял вставлять пропсы в стили через функцию. Vanilla Extract использует другой подход – вы создаете вариации (variants) с помощью функции `recipe` (из пакета `@vanilla-extract/recipes`) или динамически вычисляемые классы.
Создание темы: создайте файл `theme.css.ts` и определите контракт:
import { createTheme } from '@vanilla-extract/css';
export const [themeClass, themeVars] = createTheme({
 color: {
 primary: 'blue',
 background: 'white'
 }
});
Теперь используйте `themeVars` в ваших стилях:
export const button = style({
 backgroundColor: themeVars.color.primary,
});
Чтобы применить тему, оберните ваше приложение в div с классом `themeClass`.

Шаг 5: Замена глобальных стилей и keyframes. Глобальные стили в Emotion (`Global` компонент) заменяются на файлы `global.css.ts` с использованием функции `globalStyle`:
import { globalStyle } from '@vanilla-extract/css';
globalStyle('body', {
 margin: 0,
 fontFamily: 'Arial'
});
Анимации `keyframes` создаются с помощью функции `keyframes` и используются аналогично.

Шаг 6: Поэтапная миграция и coexistence. Не пытайтесь мигрировать всё приложение за один день. Начните с небольших, изолированных компонентов (кнопки, инпуты). Вы можете временно использовать обе библиотеки в одном проекте. Постепенно заменяйте компоненты, написанные с Emotion, на новые, использующие Vanilla Extract. Это позволит команде адаптироваться и тестировать изменения.

Шаг 7: Анализ результатов. После миграции ключевых компонентов проанализируйте bundle size. Vanilla Extract, генерируя статический CSS, обычно дает выигрыш в размере итогового бандла по сравнению с runtime-библиотеками вроде Emotion. Проверьте производительность рендеринга – отсутствие runtime-вычислений стилей должно положительно сказаться на FCP (First Contentful Paint).

Преимущества перехода: типобезопасность CSS, нулевой runtime, отличная производительность, статическое извлечение CSS. Сложности: необходимость переписывания логики динамических стилей, другая ментальная модель (не inline-стили, а классы), настройка сборки.
Этот путь требует усилий, но результат – современная, производительная и независимая кодовая база стилей, соответствующая актуальным трендам и стратегии технологического суверенитета.
239 2

Комментарии (9)

avatar
dga3eqyu9 31.03.2026
А есть ли сравнение производительности бандла после перехода? Это ключевой момент для нас.
avatar
2kt45nxuj 31.03.2026
Интересный подход, но пока остановимся на Styled Components. Слишком много легаси-кода на Emotion.
avatar
so8zmfa 31.03.2026
Не уверен, что Vanilla Extract — полная замена Emotion. Динамические стили усложняются.
avatar
jt1z1cp5 31.03.2026
Перешли полгода назад. Главный плюс — нулевая runtime-нагрузка. Статья отражает реальные сложности.
avatar
mq2ndb 01.04.2026
Жаль, что не затронули тему темизации. В Emotion это было реализовано изящнее.
avatar
17mq1cj3hqcb 02.04.2026
Автор, добавьте, пожалуйста, пример с глобальными стилями и сбросом. Это часто нужно.
avatar
q6v5nc5 02.04.2026
Спасибо за конкретные шаги. Особенно ценно, что учтена работа с TypeScript.
avatar
093whvnzgye 02.04.2026
Отличная инструкция! Как раз планируем миграцию в нашем проекте, очень своевременно.
avatar
zz0qvj 02.04.2026
Vanilla Extract — отличный выбор для новых проектов. Для миграции же придется попотеть, но оно того стоит.
Вы просмотрели все комментарии