첫 오픈소스 기여? Chakra UI v3 패키지 정리, 꼼꼼히 들여다본 이야기

Soly; 독특하게·2025년 3월 11일
post-thumbnail

Chakra UI의 핵심 개념, 패키지 구조, 그리고 개발 경험(DX)이 어떻게 변화해왔는지 직접 찾아보고 정리한 내용을 공유해보려 해요.

이번에 Chakra 레포를 분석하면서 처음으로 오픈소스에 기여해보는 경험도 했어요. 무엇이든 첫 걸음이 가장 어렵다고 하잖아요? 작은 시작이지만, 저에게는 꽤 의미 있는 시간이었어요. -> PR

그럼, 제가 분석해본 내용을 함께 살펴볼까요?


Chakra V3 에서 등장하는 용어

차크라v3에서는 다음과 같은 개념의 말들이 등장해요

1. token, semantic-token

색상, 간격 등 디자인의 기본 단위를 정의해요


1-1. tokens

고유한 기본 값을 직접 정의해요

값이 고정되어 있고, 테마(라이트/다크)에 따라 자동으로 변경되지 않아요.

ex)
export const colors = defineTokens.colors({
  black: { value: "#000000" },
  white: { value: "#FFFFFF" },
  gray: {
    100: { value: "#f5f5f5" },
    900: { value: "#1a1a1a" },
  },
});

1-2. Semantic Tokens

라이트/다크 모드에 따라 변경되는 값이에요.

a.tokens 에 정의한 값으로 유지보수에 용이하게 지정했어요.

ex)
export const colors = defineSemanticTokens.colors({
  bg: {
    DEFAULT: {
      value: {
        _light: "{colors.white}",
        _dark: "{colors.black}",
      },
    },
    subtle: {
      value: {
        _light: "{colors.gray.100}",
        _dark: "{colors.gray.900}",
      },
    },
  },
});

2.recipe, slot-recipes

컴포넌트의 스타일을 관리해요.

2-1. recipe

단일 컴포넌트에 대한 기본 스타일을 정의해요.

ex)
export const buttonRecipe = defineRecipe({
  className: "button",
  base: {
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center",
    borderRadius: "l2",
    cursor: "button",
  },
});

2-2. slot-recipe

여러 슬롯을 가진 복잡한 컴포넌트의 스타일을 정의해요.

각 슬롯(root, label, closeTrigger 등)에 개별 스타일을 적용할 수 있어요.

ex)
export const tagSlotRecipe = defineSlotRecipe({
  slots: ["root", "label", "closeTrigger"],
  className: "tag",
  base: {
    root: {
      display: "inline-flex",
      borderRadius: "l2",
    },
    label: {
      lineClamp: "1",
    },
  },
});

✅ 용어 정리

즉, 앞서 등장한 용어들을 정리하면 다음과 같이 정리할 수 있어요

3. 컴포넌트 스니펫 (Component Snippet)

컴포넌트 스니펫은 미리 정의된 UI 컴포넌트 코드 조각이에요

예를 들어 버튼, 카드, 폼 요소, 모달 등 반복해서 사용하는 UI 요소의 기본 스타일과 로직이 포함되어 있어요. 이때문에 일관된 UI 스타일을 유지하면서 개발 속도와 재사용성을 크게 높여줄 수 있는거죠.

이 방식은 일관된 UI 스타일을 유지하며 개발 속도와 재사용성을 크게 향상시킬 수 있어요


본격적으로 비교해볼까요?

4. 패키지 구조 변화

Chakra 버전 2와 버전 3은 각각의 구조와 앱 구성에 차이가 있었어요.

4-1. v2 패키지 구조

root
|- examples
|- packages
  • Examples:

Next.js, Vite, Remix 등 다양한 프레임워크에서의 사용 예제 제공

  • Packages:
    • anatomy: 컴포넌트 구조 정의
    • cli: 테마 타입 자동 완성 도구
    • components: React와 Emotion 기반 UI 컴포넌트
    • hooks, utils, theme, icons 등

ROOT- package.json

  • pnpm을 활용한 의존성 관리
// package.json 예시
{
  "pnpm": {
    "overrides": {
      "react": "^18.2.0",
      "react-dom": "^18.2.0"
    }
  }
}

4-2. v3 패키지 구조

v3에서는 앱과 패키지 구분이 보다 명확해졌어요.

root
|- apps
|- packages
  • Apps:
    • compositions (@chakra-ui/compositions): 클라이언트 전용 렌더링
    • www (@chakra-ui/www): 공식 웹사이트 구성
  • Packages:
    • panda-preset: @pandacss/types를 활용해 빌드 타임에 정적 CSS를 생성 및 상태/변형 관리
    • react, cli, hooks, styled-system, theme, utils

ROOT- package.json

  • pnpm 버전과 의존성 오버라이드를 관리
// root - package.json 예시
{
  "name": "chakra-ui",
  "pnpm": {
    "overrides": {
      "react": "18.2.0",
      "react-dom": "18.2.0",
      "prism-react-renderer": "2.4.1",
      "@emotion/react": "11.14.0"
    }
  },
  "packageManager": "pnpm@9.15.4" // (1월 말 기준)
}

V3의 다양한 컴포넌트와 모듈의 역할

Chakra UI는 단순히 UI를 렌더링하는 것을 넘어, 동작 제어와 접근성까지 고려했어요.

React 폴더가 우리가 아는 @chakra-ui/react 에요

→ stories 폴더에 스토리북 파일,

→ tests 폴더에 테스트 코드가 포함되어 있지만 일부 컴포넌트는 테스트 코드가 없는 경우도 있어요

→ 즉, ark-ui/react와 Emotion을 기반으로 제작되어 있어요

  • Components (UI 관련 기능들)

ark-UI의 State Machine 컴포넌트를 기반으로 panaChakra UI 스타일 시스템과 통합했어요

→ UI 컴포넌트 (Button, Card 등), 동작 제어 컴포넌트 (ClientOnly, Show 등), 접근성 고려 컴포넌트 (VisuallyHidden 등) 이 있어요

즉, 컴포넌트의 역할은 UI를 렌더링하는 것뿐만 아니라, 동작과 상태 관리까지 포함하고 있다는게 눈길을 끄는 점이에요.

  • Hooks

→ 반응형 디자인, 상태 관리, 이벤트 처리 등을 위한 재사용 가능한 로직들이 있어요.

  • Styled-System

→ CSS 변수 관리, 레이아웃 설정 등 효율적인 스타일링을 위한 유틸리티를 제공해요.

  • Theme

→ 색상, 크기, 간격 등 디자인 토큰을 관리해 일관된 스타일링을 제공해요.

  • Utils

→ 객체, 배열, 함수 등의 데이터 조작과 타입 확인, 속성 병합 등 다양한 유틸리티 함수 제공헤서 개발의 편의성과 효율성을 높이는 모듈이에요.


5. DX(개발 경험) 변화와 스니펫 도입

v2에서는 폐쇄형 구성 요소 중심이었지만, v3에서는 개방형 복합 구성 요소로 개선되어 유연성이 높아졌어요.

코드로 보면 다음과 같아요.

✅ v2 예시


<Checkbox iconColor='blue.400' iconSize='1rem'>
  **v2**
</Checkbox>

✅ v3 예시


<Checkbox.Root>
	<Checkbox.HiddenInput />
	<Checkbox.Control />
	<Checkbox.Label>**v3**</Checkbox.Label>
</Checkbox.Root>

마무리하며

최근에 Chakra UI를 확장해 디자인 시스템을 만드는 작업을 했어요. 그러던 중, Chakra가 v3으로 업데이트되면서 마이그레이션에 대한 고민이 생겼어요. 결과적으로는 프로덕트의 안정성을 우선시하다 보니 마이그레이션은 뒤로 미루게 되었지만, 서비스가 더 안정기에 접어들면 다시금 시도하게 될 것 같아요.

Chakra v3에서 가장 인상 깊었던 변화는 1.폴더구조의 변화와 2.DX를 한층 더 신경 썼다는 점이었어요.

첫번째로 폴더구조의 변화는 관심사 분리로 이루어진 결과물이었어요.
기존에는 하나의 레포 안에서 CSS 선언과 상태 관리를 모두 처리했다면, v3에서는 pandacss와 ark-ui/react로 역할을 분리하고, 이를 확장할 수 있도록 변화한 점이 신선했어요.

이러한 접근은 회사 서비스의 방향성과도 맞닿아 있다고 생각해요. 작은 서비스가 점차 커질 때, 무조건 모노레포로 개발하기보다는 필요에 따라 분리하고 독립적으로 개발하는 것이 더 유연할 수 있지 않을까 생각해요. Chakra가 선택한 방향처럼, 저 역시 그런 유연함을 적용해볼 필요가 있다고 판단하게 되었거든요.

두번째로 Chakra v3에서 제안하는 방식으로 사내 디자인 시스템과 UI 컴포넌트 개발에 도입해보았어요. 유연성이 확실히 좋아졌고, variation을 주는 것이 수월했어요. 물론 사용하는 곳에서 코드가 조금 더 길어지긴 했지만, 동일한 모듈을 비슷한 방식으로 사용하는 방향이 확장성 측면에서 유리하다고 느꼈어요. 덕분에 서비스의 일관성을 유지하는 데도 자연스럽게 도움이 되었어요.

Chakra UI v2와 v3을 사용해 보신 분들이 있다면, 어떻게 느끼셨는지 궁금해요.


자세한 내용은 공식문서를 참고해주세요. -> Announcing v3

profile
협업을 즐겨하는 목표지향적인, Front-End 개발자입니다.

0개의 댓글