today's helen

seize!

web

근거 있는 스타일 라이브러리 선택: Tailwind vs vanilla-extract

yooncandooit 2026. 7. 8. 15:55
반응형

들어가며

현재 우리 팀이 프로젝트 컨벤션 정하면서 스타일 라이브러리 선택에 고민이 많은데요 .. ! 😅

Tailwind파 2명, vanilla-extract파 2명으로 의견이 나뉘는 중인데, 두 라이브러리를 객관적으로 비교하고, 우리 프로젝트에 맞는 선택을 근거 있게 내리기 위해 해당 글을 작성했습니다!


비교 전, 기본 개념부터!

React와 같은 SPA가 대두되면서 CSS in JS가 많이 사용됐다고 해요. React에서는 styled-component / emotion이 그 예시인데,

CSS in JS의 장점

  1. CSS에서 JS 문법을 사용할 수 있어 생산성을 증가시킬 수 있다
  2. 지역 스코프 스타일로 className이 겹치지 않음을 보장한다
  3. 컴포넌트 파일에 관련 코드들과 동일 선상에서 같이 위치시킬 수 있다 (colocation 이라고 해요)

위와 같은 장점 덕분에 CSS in JS를 보통 많이 사용을 하지만, CSS in JS와 같은 경우 런타임에 JS 파일이 실행되면서 스타일을 생성해요. 이와 같은 런타임 CSS는 style 생성의 규모가 크고 빈번할 수록 성능이 저하될 수 있다는 단점을 가지고 있어요.

아래에서 런 타임 vs 빌드 타임 비교를 통해 조금 더 자세히 알아볼게요!

런 타임 CSS란

  • 브라우저에서 실행될 때 CSS 파일을 생성해요.
    • 작동 원리
    • 브라우저 실행 → 자바스크립트 로드 → **스타일 계산** → DOM에 삽입
  • 런타임 오버헤드가 있어요.
    • 예시로는 styled-components, Emotion

짐작은 되겠지만,, 그럼 왜 런타임 CSS가 문제일까요?

  • React의 동시 렌더링에서 CSS 스타일을 재계산 해야해요
  • 사실, 스타일 라이브러리의 무게 자체는 가벼워요. 200B로 매우 낮게 표시되고, 성능이 좋다는 Tailwind, Vanilla는 오히려 70kB로 표시되죠. 저도 조사하면서 놀랐는데요 ..
    (https://bundlephobia.com/)

emotion 라이브러리 크기

vanilla 라이브러리 크기

근데 그 이유는, 해당 스타일 라이브러리들은 개발 단계에서 필요한 컴파일러나 타입 관련 라이브러리가 모두 포함된 수치이기 때문이에요.
런타임 CSS의 번들 크기는 작을지 몰라도 브라우저가 켜진 상태에서 실시간으로 계산하는 역할이기 떄문에, 사용자의 CPU를 계속 소모하며 스타일을 만들어내는 비용(런타임 오버헤드)이 발생해요

→ 위의 문제로 인해 당연히 성능 이슈가 발생해요 !!

빌드 타임 CSS란

  • 빌드 시점에 CSS 파일을 생성해요.
    • 작동 원리
    • 개발 (코드 작성) → 빌드 → CSS 파일 생성 → 브라우저 전달 즉 - 브라우저에서 추가 연산을 할 필요가 없어요 - 초기 렌더링 속도가 빨라요
  • 런타임 오버헤드가 없어요.
    • 예시로는 Tailwind, vanila-extract

즉 우리가 고민하는 tailwind와 vanilla는 둘 다 Runtime CSS in JS의 성능상 문제점을 해결하기 위해 등장한 Zero-runtime CSS in JS 스타일 라이브러리네요!!!


비교

위에서 살펴봤듯 둘 다 zero-runtime 방식이라는 공통점이 있네요!

그럼 이제부터 개발 경험(DX)과 유지보수 측면에서 두 라이브러리를 비교해 볼게요!

Tailwind CSS 찬반 의견 분석

https://www.reddit.com/r/reactjs/comments/1hey5ma/why_almost_everyone_i_see_uses_tailwind_css_whats/

→ 위는 tailwind의 찬반을 다루고 있는 reddit 링크예요.
약 400개의 타당한 의견이 있는데 제가 (객관적으로ㅎㅎ) 요약해 볼게요!

vanilla-extract 분석

“stylesheets in TypeScript”

위 인용문구는 vanilla-extract 공식 문서에서도

자랑스럽게

강조하고 있는 문구로, 타입이 안전한 CSS-in-TS로, TypeScript로 CSS를 작성하는 라이브러리예요.

여러 블로그들을 참고해서 바닐라의 몇 가지 특징을 정리해 보았어요!

  • 타입스크립트를 사용하기 때문에 type-safe하게 핸들링할 수 있다
  • 빌드 타임에 ts파일을 CSS 파일로 만든다
  • sprinkles, recipe, dynamic과 같은 도구를 통해 다양한 스타일을 구성할 수 있다
    • vanilla-extract의 sprinkles, recipe, dynamic 요약sprinkles를 통해 tailwind처럼 atomic하게 css를 구성할 수도 있고,dynamic을 활용하여 동적으로 값을 업데이트하는 등 되게 다양하게 활용할 수 있는 방안들이 많은 것 같아요
      ⭐️ 링크
      자세한 건 위 레퍼런스를 참고하면서 저도 익혀볼 예정이예요!
    • recipe를 활용하여 variant 기반 스타일링을 구성하거나,
    • 요약하자면,
    ---

Tailwind를 모방한 Sprinkles, Sttiches을 모방한 Recipes 그리고 Linaria를 모방한 dynamic을 제공하기 떄문에 Vanilla Extract의 조금 부족했던 사용성도 보완이 되어서, “거의 모든 CSS in JS를 총망라 했다”라는 평을 받고 있어요!


마무리

프로젝트에 맞는 스타일 선택 가이드

위 특징을 정리해보니 어느 상황에서 어느 라이브러리를 선택할 지 조금 감이 잡혀서 프로젝트에 맞는 스타일 선택 가이드를 적어볼게요!

  • 스타일을 빠르게 작성하려면
  • 파일 전환 없이 스타일을 부여하려면
  • 규칙 통일로 일관성이 중요하다면

Tailwind

  • 장기적으로 유지보수하려면
  • 타입 안정성이 중요하다면
  • 복잡한 동적 스타일링이 있다면

vanilla-extract


추가로 서치해보다가 Next.js + vanilla-extract의 조합에 대한 글을 발견했어요 (링크)

저도 해당 조합을 사용해본 건 아니지만 ..

만약 우리가 넥제를 사용하게 된다면 바닐라 스타일 라이브러리는 지양하고 다른 대안을 찾아보는게 좋을 거 같네요!

반응형