bythe.net
← К ленте
Тренд

cn: замена tailwind-merge и clsx с заявленным 30-кратным ускорением — что нужно знать перед миграцией

Новая библиотека cn (shadcn-ui) позиционируется как drop-in замена tailwind-merge и clsx с полной паритетностью API. Репозиторий свежий (создан 31.08.2026), 1168★, 9 форков.

Что произошло

В экосистеме shadcn-ui появился новый пакет cn — движок для мерджа Tailwind-классов и разрешения конфликтов. Заявлена полная паритетность API с tailwind-merge и clsx, то есть предполагается drop-in замена без изменения кода вызовов. Заявленная разница в производительности — 30×.

Репозиторий: shadcn-ui/cn, звёзд — 1168, форков — 9, язык — TypeScript, создан 2026-08-31.

Почему это важно операторам

tailwind-merge и clsx — транзитивные зависимости огромного количества UI-компонентов на базе shadcn/ui и Tailwind. Замена движка мерджа классов затрагивает:

  • рендеринг классов на клиенте и сервере (SSR/RSC);
  • поведение при конфликтах утилитарных классов (например, p-2 vs px-4);
  • бандл-сайз и cold-start в serverless-окружениях.

Репозиторий очень молодой (меньше месяца на момент сигнала), 9 форков — сообщество ещё не успело провести аудит edge-кейсов. Заявленное «полное соответствие API» стоит проверять эмпирически, а не принимать на веру.

Риски перед внедрением

  1. Отсутствие production-истории. Нет данных о поведении в высоконагруженных или edge-кейсах (динамические классы, arbitrary values, важные модификаторы !).
  2. Нет данных о покрытии тестами в самом сигнале — нужно смотреть CI в репозитории перед пином версии.
  3. Скрытые различия в разрешении конфликтов — даже при «той же API» логика мерджа может давать иной итоговый набор классов в граничных случаях (важно для регрессионного тестирования UI).

Чеклист перед миграцией

# 1. Зафиксировать текущие версии перед экспериментом
npm ls tailwind-merge clsx --depth=0
# 2. Установить cn в отдельной ветке/окружении
npm install cn@latest --save-exact
# 3. Не удалять старые зависимости сразу — держать side-by-side для сравнения

Сравнительный тест на реальных наборах классов из проекта:

import { cn as cnNew } from 'cn';
import { twMerge } from 'tailwind-merge';
import clsx from 'clsx';
const cases: string[][] = [
['p-2', 'px-4'],
['bg-red-500', 'bg-blue-500'],
['text-sm', 'sm:text-lg', 'text-sm'],
// добавить реальные сочетания классов из вашей кодовой базы
];
for (const c of cases) {
const oldResult = clsx(...c) && twMerge(clsx(...c));
const newResult = cnNew(...c);
if (oldResult !== newResult) {
console.error('MISMATCH', c, { oldResult, newResult });
}
}

Запустить этот скрипт против снапшота реально используемых классов в проекте (можно извлечь grep'ом по className=) — до замены в prod-бандле.

Рекомендации

  • Не заменять tailwind-merge/clsx в критичных путях до появления минорных релизов и внешнего аудита (сейчас это pre-1.0 экосистемный риск).
  • Пиновать точную версию (--save-exact), не диапазон, пока пакет нестабилен.
  • Добавить визуальный regression-тест (Percy/Chromatic или скриншот-diff) на ключевые компоненты перед merge в main.
  • Отслеживать issues/PR в репозитории на предмет edge-кейсов с конфликтами important-модификаторов и arbitrary values — это исторически самое частое место багов у мердж-движков Tailwind-классов.
  • Если проект в проде использует SSR/RSC — отдельно протестировать поведение на сервере, так как заявленное ускорение может быть привязано к рантайм-окружению, не указанному в сигнале.

Итог

Заявка на 30× ускорение и полную паритетность API привлекательна, но при возрасте репозитория менее месяца и малом числе форков — это повод для пилотного тестирования в изолированной ветке, а не для немедленной замены в проде.

Войти, чтобы оценить материал

Комментарии

Войти, чтобы оставить комментарий