[react] Zero-Runtime과 서버 컴포넌트(RSC) 시대의 스타일링
2025년 5월 5일
App Router 이후 styled-components, emotion 같은 런타임 CSS-in-JS가 문제가 됐다. 런타임에 스타일을 주입하는 구조 때문에 Server Component에 쓸 수 없고, 쓰려면 컴포넌트를 'use client'로 강제 전환해야 한다.
Tailwind로 갈 수도 있는데, 클래스 속성이 길어지는 게 싫거나 JS/TS로 스타일을 캡슐화하고 싶다면 Zero-Runtime CSS-in-JS가 대안이다.
Zero-Runtime의 빌드 타임 CSS 추출 원리
문법은 기존 CSS-in-JS와 비슷하다. JS/TS 안에서 객체로 스타일을 작성한다.
차이는 스타일이 언제만들어지느냐다.
런타임 방식은 브라우저가 JS 번들을 실행할 때 <style> 태그를 동적으로 주입한다. Zero-Runtime은 번들러가 빌드할 때 스타일 코드를 분석해 .css 파일로 뽑아낸다. 브라우저로 내려가는 JS 번들에는 스타일 생성 로직이 없다.
Server Component에서 쓸 수 있는 이유
런타임 CSS-in-JS는 React Context나 훅에 의존하기 때문에, 스타일이 적용된 컴포넌트는 'use client'가 강제된다. Server Component에서 쓸 수 없다.
Zero-Runtime은 빌드 타임에 .css 파일이 이미 만들어져 있다. Next.js가 이를 <link rel="stylesheet">로 주입하기 때문에 Server Component에서도 제약 없이 쓸 수 있다. JS/TS로 스타일을 캡슐화하면서 컴포넌트를 Server Component로 유지할 수 있다.
주요 라이브러리
- Vanilla Extract: TypeScript 친화적이다.
.css.ts확장자를 쓰며, 잘못된 속성 값이나 오타를 컴파일 단계에서 잡아준다. - Panda CSS: Chakra UI 팀이 만들었다. Tailwind 스타일의 유틸리티 클래스를 JS/TS에서 타입 안전하게 쓸 수 있다.
- StyleX: Meta에서 내부 사용 후 오픈소스로 공개했다. 대규모 앱의 CSS 충돌과 용량 문제를 Atomic CSS로 해결한다.