JiSoo's Devlog
🐼 Panda CSS 본문
여러분은 어떤 CSS 라이브러리를 선호하시나요?
저는 개인적으로 최근에는 Vanilla Extract를 자주 사용했었는데요!
최근 들어 새로운 스타일링도 도전해보고 싶다는 생각이 들었어요.
요즘 Panda CSS 라이브러리에 관심이 생겨서
이번 기회에 직접 공부하면서 어떤 특징이 있는지 정리해보려고 합니다!😄
🧠 CSS-in-JS
리액트로 개발해 본 분들이라면 한 번쯤은 Styled-components나 Emotion을 써본 경험이 있으실 텐데요.
이 라이브러리들은 컴포넌트 단위로 스타일을 관리할 수 있고 JS 안에서 바로 스타일을 작성할 수 있다는 점에서 개발자 경험이 뛰어났습니다.
하지만!
프로젝트 규모가 커질수록 여러 문제가 생기가 시작했어요..
CSS-in-JS는 런타임에 스타일을 생성하기 때문에 앱이 커질수록 번들 크기가 커지고 렌더링 성능이 떨어지는 문제가 생깁니다.
또한 스타일을 문자열로 작성하다 보니 타입 안정성이 부족해 오타나 잘못된 값이 컴파일 시점에 잡히지 않는다는 단점도 있었어요.
이런 문제를 해결하기 위해 등장한 게 바로
“빌드 타임에 스타일을 생성하는 Zero-runtime 스타일링”인데요
Vanilla Extract, StyleX, Panda CSS 등이 여기 속해요.
🐼 Panda CSS 등장
Panda CSS는 이런 흐름 속에서 등장한 타입 안전한 디자인 시스템 중심 스타일링 프레임워크입니다.
CSS-in-JS의 편리한 작성 경험은 그대로 유지하면서
런타임이 아닌 빌드 타임에 Atomic CSS를 생성해 성능을 극대화해요!
또한 디자인 토큰 시스템을 기본 제공해, 색상·여백·폰트 같은 스타일 값을 일관되게 관리할 수 있습니다.
정리하자면 Panda CSS는
CSS-in-JS의 개발자 경험 + Atomic CSS의 성능 + 타입 안정성 + 디자인 토큰
이것들을 모두 담은 스타일링 라이브러리입니다.
⚖️ 다른 라이브러리와 비교
| 비교 항목 | Vanilla Extract | Tailwind CSS | Panda CSS |
| 스타일 생성 시점 | 빌드 타임 | 빌드 타임 | 빌드 타임 |
| 성능 | 매우 빠름 | 매우 빠름 | 매우 빠름 |
| 타입 안전성 | 지원 | 비코드 기반 (클래스 문자열) | 지원 |
| 디자인 토큰 시스템 | 가능(수동 구성) | 설정 파일에서 일부 지원 | 기본 내장 |
| 개발자 경험 | 설정 복잡 | 빠른 UI 작성 | Chakra UI와 유사한 문법 |
| 런타임 의존성 | X | X | X |
| 러닝 커브 | 약간 높음 | 낮음 | 중간 |
| 스타일 관리 방식 | Type-safe 모듈 구조 | Utility 클래스 조합 | Token + Atomic 구조 |
⚙️ 기본 사용법
1) 설치 및 초기화
# 설치 (dev 툴 + 컴포넌트 스타일 작성용)
npm add -D @pandacss/dev
npm add @pandacss/styled
# 초기 설정 파일 생성 (질문에 따라 기본 템플릿 생성)
npx panda init
# 또는 스크립트로
# package.json -> "scripts": { "panda": "panda", "panda:watch": "panda --watch" }
# pnpm run panda
2) panda.config.ts 예시
import { defineConfig } from "@pandacss/dev";
export default defineConfig({
// 스타일을 스캔할 파일들
include: ["./src/**/*.{ts,tsx,js,jsx}"],
exclude: ["**/node_modules/**"],
// 생성물 출력 폴더(자동 생성)
outdir: "styled-system",
// 필요하면 토큰/프리셋 확장
theme: {
tokens: {
colors: {
brand: { 500: { value: "#4F46E5" }, 600: { value: "#4338CA" } },
},
radii: { lg: { value: "12px" } },
spacing: { 4: { value: "1rem" } },
},
},
});
3) 전역 CSS 연결
빌드 시 생성되는 전역 CSS를 한 번만 임포트합니다.
Vite, CRA, SPA → src/main.tsx 혹은 index.tsx
Next.js (App Router) → app/layout.tsx
import "../styled-system/styles.css";
4) 컴포넌트에서 사용하기
styled() - 컴포넌트 래퍼
// src/components/Button.tsx
import { styled } from "@pandacss/styled";
export const Button = styled("button", {
base: {
bg: "brand.500",
color: "white",
px: 4,
py: 2,
rounded: "lg",
_hover: { bg: "brand.600" },
},
});
// 사용
<Button>확인</Button>
css() - 클래스 유틸
import { css } from "../styled-system/css";
const box = css({
p: 4,
bg: "gray.100",
rounded: "lg",
});
export function Card({ children }: { children: React.ReactNode }) {
return <div className={box}>{children}</div>;
}
5) 코드젠 & 워치
개발 중 자동으로 스타일을 생성/갱신하려면 워치를 같이 돌리면 돼요.
// package.json
{
"scripts": {
"dev": "next dev",
"panda": "panda",
"panda:watch": "panda --watch",
"build": "panda && next build"
}
}
로컬 개발
pnpm run panda:watch # 터미널 1: 스타일 감시
pnpm dev # 터미널 2: 앱 실행
프로덕션 빌드
pnpm build # 빌드 전에 CSS를 정적으로 생성
6) 결과물 확인: 정적 CSS 생성
Panda는 정적 분석 → 필요한 CSS만 즉시 생성
생성 폴더: styled-system
전역 파일: styled-system/styles.css
타입 안전/토큰 자동완성용 타입 선언과 유틸이 함께 생성됩니다.
👉🏻 런타임에 스타일을 계산하지 않고 빌드 타임에 미리 CSS를 만들어두기 때문에 번들/성능 이점이 큽니다!
🎨 디자인 토큰 시스템
디자인 토큰이란?
다들 아시겠지만 디자인 토큰은 디자인 속성들을 변수처럼 관리하는 시스템이에요.
Panda CSS의 가장 큰 특징은 디자인 토큰 기반의 스타일링이에요.
이 방식을 사용하면 프로젝트 전반의 스타일을 구조적으로 관리할 수 있고 많은 컴포넌트들에서도 일관된 UI/UX를 유지할 수 있어요!
디자인 토큰은 왜 중요할까요?
Tailwind CSS는 빠르고 직관적인 반면 클래스가 길어지고 색상이나 간격들이 어디서 왔는지 추적하기 어려운 경우가 많아요.
반면 Panda는 토큰을 기반으로 스타일을 선언적으로 관리하기 때문에 토큰 이름만 봐도 어떤 역할을 하는 건지 바로 알 수 있죠!
토큰 구조
panda.config.ts 안에서 바로 정의해도 되고
별도 파일로 분리해서 관리할 수도 있어요.
// tokens/colors.ts
export const colors = {
brand: {
50: { value: "#EEF2FF" },
100: { value: "#E0E7FF" },
500: { value: "#4F46E5" },
600: { value: "#4338CA" },
},
gray: {
50: { value: "#F9FAFB" },
900: { value: "#111827" },
},
}
// panda.config.ts
import { defineConfig } from "@pandacss/dev"
import { colors } from "./tokens/colors"
export default defineConfig({
theme: {
tokens: { colors },
},
})
import { styled } from "@pandacss/styled"
const Button = styled("button", {
base: {
bg: "brand.500",
color: "white",
px: 4, // spacing token
py: 2,
fontSize: "lg", // fontSize token
rounded: "lg",
_hover: { bg: "brand.600" },
},
})
빌드 시 Panda가 brand.500 → #4F46E5, px: 4 → padding-left/right: 1rem 으로 변환해서 정적 CSS를 자동 생성합니다.
전역 테마 설정 & 다크 모드
Panda는 토큰을 기반으로 여러 테마를 쉽게 확장할 수 있어요.
예를 들어 아래 코드처럼 라이트/다크 코드도 구성할 수 있습니다.
// panda.config.ts
theme: {
extend: {
semanticTokens: {
colors: {
bg: {
default: { value: "{colors.gray.50}" },
_dark: { value: "{colors.gray.900}" },
},
text: {
default: { value: "{colors.gray.900}" },
_dark: { value: "{colors.gray.50}" },
},
},
},
},
}
const Box = styled("div", {
base: {
bg: "bg",
color: "text",
p: 8,
},
});
이렇게 하면 다크 모드 전환 시 자동으로 토큰이 바뀌면서 컴포넌트를 따로 수정할 필요가 없겠죠?
🌱 타입 안정성의 장점
CSS-in-JS를 쓰다 보면 종종 이런 실수를 하는 경우가 있는데요😅
<Button backgroundClor="blue" /> // 'backgroundColor' 오타!!
Panda CSS는 이러 문제를 !타입!으로 해결합니다!
Panda CSS는 TypeScript 기반의 완전한 타입 안전 스타일링 시스템이에요.
모든 스타일 속성, 토큰 값, 유틸리티 함수에 자동 완성이 지원됩니다.
VSCode에서 타이핑하는 순간 가능한 옵션이 전부 뜨기 때문에 오타나 잘못된 속성을 입력할 수 없어요.
import { styled } from "@pandacss/styled"
const Box = styled("div", {
base: {
bg: "brand.500",
color: "white",
px: 4,
fontSize: "lg",
hover: { bg: "brand.600" }
},
})
위 코드의 경우에 bg의 값을 입력할 때 brand.라고만 입력해도 자동으로 토큰 목록이 뜨는 걸 보실 수 있습니다.
또한 잘못된 토큰 이름을 입력하면 빌드 시점에서 에러로 잡히게 돼요.
대부분의 CSS 관련 문제는 런타임에 발견되는데
Panda CSS는 정적 분석을 사용하기 때문에
스타일 관련 문제를 빌드 단계에서 미리 감지할 수 있습니다!
🐤 Panda CSS 장단점
Panda CSS는 타입 안전성과 성능, 그리고 디자인 시스템 중심 구조라는 강력한 장점을 갖고 있지만
아직 비교적 새로운 생태계이기 때문에 고려해야 할 부분도 있어요.
😸 장점
1️⃣ Zero-runtime으로 빠른 성능
Panda는 빌드 타임에 정적 CSS를 생성하기 때문에 런타임에서 계산할 필요가 없어요.
그래서 CSS-in-JS에서 흔했던 렌더링 지연, 번들 증가 문제를 해결해 줍니다.
2️⃣ 완전한 타입 안전성(Type-safe)
TypeScript 기반으로 동작하기 때문에 스타일 속성이나 토큰을 입력할 때 자동완성과 타입 검증이 이루어지기 때문에
오타, 잘못된 속성값, 누락된 스타일을 사전에 방지할 수 있습니다.
3️⃣ 디자인 토큰 시스템 내장
색상, 간격, 폰트, 브레이크포인트 등 디자인 속성을 전역적으로 통일할 수 있어요.
디자인 시스템 기반으로 프로젝트를 구성할 때 매우 강력한 구조예요.
4️⃣ CSS-in-JS의 개발자 경험은 그대로 유지
styled(), css() 같은 문법이 Chakra UI와 유사해서 직관적으로 사용할 수 있고 러닝 커브가 낮습니다.
😿 단점
1️⃣ 생태계가 아직 작음
Styled-components나 Tailwind처럼 대규모 커뮤니티가 형성된 단계는 아닙니다.
그렇기 때문에 자료나 예시가 상대적으로 적어서 문제를 해결할 때 직접 문서를 찾아야 할 때가 많아요.
2️⃣ 초기 설정이 다소 생소함
panda.config.ts, tokens/ 구조 등
처음엔 설정 파일이 많아 보여서 진입 장벽이 느껴질 수 있습니다.
하지만 한 번 구조를 잡으면 오히려 관리가 쉬워집니다.
3️⃣ 빌드 전 단계 필요
정적 CSS를 생성하기 때문에 매 빌드 시 panda 명령어를 실행해야 해요.
→ panda --watch로 자동화하면 해결 가능
🤔 프로젝트 도입 시 고려할 점
Panda CSS는 CSS-in-JS의 개발 경험을 그대로 유지하면서도
성능, 타입 안정성, 구조적 일관성을 모두 잡았다는 점이 가장 큰 강점인데요.
Panda CSS가 잘 맞는 경우
- 팀에서 디자인 토큰 기반 시스템을 운영하고 있는 경우
- 프로젝트에서 다크 모드 등 확장 가능한 스타일 구조가 필요한 경우
- CSS-in-JS를 써봤지만 성능 문제나 유지보수 이슈를 겪었던 경우
- TypeScript를 중심으로 개발하며 자동완성과 안정성을 중시하는 경우
아직은 다른 라이브러리에 비해 새로운 라이브러리지만
디자인 시스템 중심의 개발을 목표로 한다면 충분히 도입할 만한 가치가 있다고 생각해요.
각자의 프로젝트 성격에 맞는 스타일링 라이브러리를 사용하시면 좋을 것 같아요 🌟🐼
🔗 참고
Panda CSS - Build modern websites using build time and type-safe CSS-in-JS
Build modern websites using build time and type-safe CSS-in-JS
panda-css.com
https://github.com/chakra-ui/panda
GitHub - chakra-ui/panda: 🐼 Universal, Type-Safe, CSS-in-JS Framework for Design Systems ⚡️
🐼 Universal, Type-Safe, CSS-in-JS Framework for Design Systems ⚡️ - chakra-ui/panda
github.com