When Not to Mix — 두 시스템을 섞지 말아야 하는 케이스
이 문서가 답하는 질문: Panda CSS와 Tailwind를 한 프로젝트에서 섞는 것이 답이 아닐 때는 언제인가? 한 줄 답 (Pyramid Top): 호환은 기술적으로 가능하지만 조직적·인지적 비용은 두 배다. 팀 규모가 작거나 디자인 시스템이 아직 안정되지 않았거나 빌드 시간이 이미 한계라면 한쪽만 선택하라.
Why — 왜 존재하는가
이전 7개 문서는 “어떻게 섞을 수 있는가”를 다뤘다. 이 문서는 “섞지 말아야 할 때” 를 다룬다. 호환 가능성이 해야 함을 의미하진 않는다.
| 호환의 비용 | 구체적으로 |
|---|---|
| 인지 부하 2배 | 새 멤버가 두 시스템의 mental model을 익혀야 함 |
| 빌드 시간 1.5~2배 | Panda extract + Tailwind JIT 동시 작동 |
| 의사결정 비용 | ”이건 recipe? utility?” 매번 판단 |
| 토큰 동기화 위험 | 한쪽에만 토큰 추가 → 다른 쪽에서 IDE 자동완성 안 됨 |
| 의존성 보안 surface 2배 | CVE 추적·업그레이드 작업이 두 곳 |
이 비용은 조직적이지 기술적이 아니다. 그래서 “기술적으로 풀린다”고 자동으로 정당화되지 않는다.
How — 어떻게 결정하는가
판단 트리:
- 디자인 시스템이 아직 진화 중인가? → 토큰이 매주 바뀌면 두 시스템에 동기화하는 비용이 크다. 한쪽만.
- 팀 규모가 작은가? → 5명 이하 팀에 두 시스템을 유지할 인지·문서화 자원이 부족하다.
- 마이그레이션 중인가? → 섞기는 한시적 정당화. 끝나는 데드라인과 끝났을 때 어느 쪽만 남을지를 사전에 명시.
- recipe와 utility를 둘 다 강하게 필요한가? → 한쪽이 충분히 좋다면 굳이 두 개.
What — 구체 사양·수치·예시
”Tailwind만”이 더 나은 케이스
- 디자인 시스템이 컴포넌트 카탈로그보다 유틸리티 정의에 가까울 때 (마케팅 사이트, CMS 기반 페이지)
- 팀이 React 외 다양한 프레임워크를 쓸 때 (Astro·Svelte·Vue 혼재) — Tailwind는 framework agnostic
tailwind-variants+ Headless UI로 대부분의 컴포넌트 요구가 풀릴 때- DX는 좋지만 zero-runtime이 굳이 필요 없을 때 (대부분의 SPA는 1KB 차이 영향 없음)
“Panda만”이 더 나은 케이스
- 타입 안전한 토큰이 강하게 필요한 라이브러리 코드 (디자인 시스템 자체)
- zero-runtime이 production 요구사항 (RSC·streaming SSR의 first paint 최적화)
- 컴포넌트 라이브러리를 npm 패키지로 배포하면서 사용자가
tailwind.config없이도 쓰게 하고 싶을 때 - recipe + slot recipe + compoundVariants가 디자인 시스템의 1급 기능일 때
”섞기”가 정당화되는 케이스
- 모노레포에서 패키지별 분담:
packages/ui(Panda),apps/marketing(Tailwind),apps/admin(Tailwind),apps/portal(Panda) — 같은 토큰 출처, 다른 빌드 시스템. - 마이그레이션 (Tailwind → Panda): 6~12개월 단위 데드라인. 새 코드는 Panda, 기존 코드는 Tailwind. 데드라인까지 모든 Tailwind 코드를 Panda로 변환 (codemod).
- 레거시 시스템 + 신규 라이브러리: 5년 된 admin 페이지가 Tailwind이고, 새로 만든 디자인 시스템을 영입해야 할 때. 신규는 Panda(타입 안전), 레거시는 Tailwind(점진 변환).
”섞기”가 자기기만인 케이스
- “둘 다 좋아 보여서” — 의사결정 회피. 기술 부채.
- “팀원마다 선호가 달라서” — 코드 일관성 부재. 신규 멤버가 무엇을 배워야 할지 모름.
- “마이그레이션 중인데 데드라인이 없음” — 영구적 hybrid → 영구적 두 배 비용.
- “유틸리티는 Tailwind, 컴포넌트는 Panda”인데 경계가 모호함 — “이건 컴포넌트야 아니야”를 매번 회의로 결정해야 함.
의사결정 체크리스트
배포 전 다음 5개에 모두 YES면 섞기 가능:
- 마이그레이션 데드라인이 캘린더에 박혀 있는가? (또는 영구적 분리가 패키지 경계로 명확한가?)
- 토큰 단일 출처(
tokens.json)가 코드 외부에 존재하는가? - 빌드 시간이 마이그레이션 중 1.5배 증가를 감당할 수 있는가?
- 신규 멤버 onboarding 문서에 “언제 어느 시스템을 쓰는가” 1페이지가 있는가?
- CI에 “양쪽 시스템이 같은 토큰을 가리키는가” 검증 스크립트가 있는가?
What-if — 잘못 쓰면 어떻게 깨지는가
- “마이그레이션”이라며 시작했는데 1년 후 영구화: 결국 두 배 비용. 마이그레이션 시작 시 끝나는 조건과 완료 점검 기준을 명시.
- 토큰을 한쪽에만 추가하고 동기화 잊음:
tailwind.config에는colors.brand-2: ...추가,panda.config엔 안 함. → CI에 토큰 diff 검증. - 팀 분파 형성: “Panda 진영 vs Tailwind 진영”으로 코드 리뷰가 정치화. → tech lead가 경계와 결정자를 명문화.
- 신규 멤버가 어느 쪽도 잘 못 씀: 표면적으로만 두 시스템 다 쓰지만 각 시스템의 깊은 기능(recipe slot, compoundVariants)을 모름. → 한쪽만 깊게.
- 빌드 시간 폭증 → DX 저하 → 우회 hack 등장: HMR이 느려져서
style={{}}inline style로 회피 → 디자인 시스템 우회.
Insight — 흥미로운 이야기
소프트웨어 아키텍처에서 “둘 다”의 유혹은 흔하다 — Redux와 Context, REST와 GraphQL, SQL과 NoSQL. 대부분의 경우 조직이 결정을 미루는 비용이 기술적 비용을 능가한다.
흥미로운 사례: 2023년 Linear는 내부 디자인 시스템을 Tailwind에서 vanilla CSS-in-JS로 완전 마이그레이션했다. 사유는 “Tailwind의 limitation이 아니라 결정의 단일화가 중요했다”. 6개월 마이그레이션 후 빌드 시간 30% 감소, 신규 멤버 onboarding 시간 절반.
반면 GitHub Primer는 의도적으로 양립한다 — @primer/react는 styled-system 기반(컴포넌트), 사용자는 Tailwind도 쓸 수 있게(유틸리티). 단, 경계가 패키지 단위로 명확하고, 두 시스템이 같은 토큰 JSON을 코드 외부에서 가리킨다는 점이 다르다.
핵심 통찰: 호환 가능성은 기술 결정이 아니라 조직 설계 결정이다. “우리 조직은 두 시스템을 동시에 유지할 문서화·CI·tech lead 시간을 감당할 수 있는가?”라는 질문이 핵심.
요약
- 호환은 가능하지만 비용은 두 배다 (조직적·인지적).
- 한쪽만 쓰는 게 정당화되는 케이스: 작은 팀, 진화 중인 디자인 시스템, recipe/utility 한쪽만 강하게 필요.
- 섞기는 명확한 경계가 있을 때만 — 패키지 경계 또는 마이그레이션 데드라인.
- 5개 체크리스트로 자기기만 방어.