[스타일링 방식 의사결정] CSS-in-JS와 tailwind css 비교

Innes·2025년 4월 30일
0

💬 배경

프로젝트 들어가기 앞서, next.js를 도입하는 프론트엔드 프로젝트에서 가장 이상적인 스타일링 방법이 무엇인지 고민이 생겼다.
최근 emotion을 쓰고 있는 회사들이 많다고 들어서 이번 기회에 우리 프로젝트에도 도입해볼까 하는 생각에 emotion이 어떤 건지 조사해보니 styled-components같은 css-in-js 스타일링이라는 걸 알게 됐고, 이를 바탕으로 tailwind css와 비교하여 어떤게 더 좋은지 비교해 본 내용을 아래와 같이 정리한다.

(emotion 도입 고민에 박차를 가하게 만든 아래의 npm trends 그래프. styled-components보다 다운로드 수가 높은걸 보고 제대로 비교해봐야겠다는 생각이 들었다.)

🔗 npm trends에서 emotion/react, styled-components, tailwindcss 비교


🧵 CSS-in-JS vs Tailwind CSS (Next.js 기준 비교)

항목Emotion / Styled-Components (CSS-in-JS)Tailwind CSS
💡 스타일 정의 방식JavaScript 안에서 styled 또는 css로 정의 (동적)정적 className 기반 유틸리티 CSS
⚙️ 실행 시점런타임에 JS로 스타일 생성 및 삽입빌드 타임에 class 기준으로 CSS 생성
⚡ 성능 (렌더링 & hydration)props 기반 스타일 재계산 발생 → 렌더/하이드레이션 지연 가능성 있음정적 class 적용 → 렌더/하이드레이션 매우 빠름
🧠 서버 컴포넌트 (RSC) 호환성제한적. JS 기반 스타일 계산이 서버 컴포넌트 흐름에 맞지 않음매우 우수. 정적 CSS는 RSC와 자연스럽게 통합됨
🧩 런타임 CSS rule 처리렌더될 때마다 <style> 태그에 CSS rule이 계속 추가됨사전에 purge된 CSS만 사용됨, 추가 없음
🧮 번들 크기추가 JS 코드 포함 (약 20~35KB gzipped)거의 없음 (purge된 CSS만 사용)
🔁 중복 스타일 이슈동일한 스타일이라도 여러 컴포넌트에서 각각 rule 생성 가능동일 className 재사용됨 (중복 없음)
🔧 동적 스타일링매우 유연 (props 기반 조건부 스타일)class 조합으로 구현 (clsx, classnames 등 필요)
🧪 디버깅className이 해시화되어 추적 어려움 (css-abc123)직관적인 className (bg-blue-500, text-sm 등)
🎯 개발 경험컴포넌트 단위 스타일 관리 편리초반엔 class 조합 복잡해보일 수 있으나 익숙해지면 빠름
📦 설치 및 설정별도 설정 필요 (babel-plugin, SSR 지원 등 고려)PostCSS 기반 설정만으로 간단히 가능
  • 스타일 방식:
    CSS-in-JS는 JS 안에서 styled나 css 함수를 통해 스타일을 정의하고, Tailwind는 미리 정의된 className을 조합해 사용하는 방식이다.

  • 실행 시점:
    CSS-in-JS는 렌더링 중에 스타일을 동적으로 생성하는 반면, Tailwind는 빌드 시 정적 class만 포함되므로 클라이언트에서 추가 연산이 없다.

  • hydration 성능:
    CSS-in-JS는 props 기반 스타일 재계산이 필요해 hydration 속도가 느려질 수 있고, Tailwind는 정적 class로 인해 매우 빠르고 안정적이다.

  • 서버 컴포넌트(RSC) 호환성:
    CSS-in-JS는 런타임 기반이라 RSC 흐름과 잘 맞지 않지만, Tailwind는 서버 컴포넌트 구조와 완전히 호환된다.

  • 런타임 스타일 처리:
    CSS-in-JS는 렌더링마다 새로운 CSS rule을 <style> 태그에 추가하고, Tailwind는 미리 정리된 class만 사용하므로 성능에 부담이 없다.

  • 번들 크기:
    CSS-in-JS는 약 20~35KB(gzipped)의 JS 코드를 추가하고, Tailwind는 purge된 최소한의 CSS만 포함되어 훨씬 가볍다.

  • 중복 스타일:
    CSS-in-JS는 같은 스타일도 컴포넌트마다 새롭게 생성되기 쉬우며, Tailwind는 className을 재사용하기 때문에 중복이 없다.

  • 동적 스타일링:
    CSS-in-JS는 props 기반으로 유연하게 처리할 수 있고, Tailwind는 조건부 class 조합(clsx, classnames)이 필요하다.

  • 디버깅 편의성:
    CSS-in-JS는 해시 class로 인해 디버깅이 어려운 반면, Tailwind는 의미 있는 class명이라 추적이 쉽다.

  • 개발 경험:
    CSS-in-JS는 컴포넌트 단위 스타일링이 익숙한 사람에게 편리하지만, Tailwind는 한번 익숙해지면 빠른 개발이 가능하고 유지보수가 편하다.

  • 설정 난이도:
    CSS-in-JS는 SSR 지원과 Babel 설정 등 별도 설정이 필요하지만, Tailwind는 PostCSS 기반의 단순한 설정으로 빠르게 도입 가능하다.


✍️ 결론

Next.js의 가장 큰 장점은 Server-Side Rendering(SSR) 및 React Server Components(RSC)를 통해 서버에서 미리 HTML을 렌더링하고 클라이언트에 전달함으로써 최적의 퍼포먼스를 확보하는 것이다.
하지만 Emotion이나 Styled Components처럼 JS 기반 CSS-in-JS는 이러한 구조와 맞지 않는 실행 흐름과 런타임 비용, 그리고 hydration 단계에서의 불리함이 존재한다.

특히 props 기반 동적 스타일링은 렌더링 및 hydration 시점마다 스타일 재계산이 필요하여 브라우저 성능에 부담을 줄 수 있고, <style> 태그에 css rule이 누적되면서 style tree도 무거워질 수 있다.

이에 반해 Tailwind CSS는 정적으로 미리 정의된 className만 사용되기 때문에 hydration 시 연산이 없고, 서버 컴포넌트와 완벽히 호환되며, 번들 크기도 최소화할 수 있어 Next.js의 철학과 구조에 가장 잘 맞는 스타일링 도구라고 판단했다.

👉 따라서, 이번 프로젝트에서는 Tailwind CSS를 스타일링 도구로 선택했다.

profile
무서운 속도로 흡수하는 스펀지 개발자 🧽

0개의 댓글