REPO DEEP DIVE · 2026-07-29 · CARBON-DESIGN-SYSTEM/CARBON · IBM 디자인 시스템의 토큰·Sass·React 해부

carbon-design-system/carbon 딥다이브
"디자인을 코드로 굳힌" IBM의 오픈소스 디자인 시스템

Carbon은 IBM이 만들고 관리하는 오픈소스 디자인 시스템이다. 색·간격·타이포·그리드 같은 디자인 결정을 "토큰"이라는 데이터로 고정하고, 그 토큰 위에 127개 이상의 React 컴포넌트와 그에 대응하는 웹 컴포넌트(Lit) 버전을 함께 제공하는 대형 모노레포다.

가장 중요한 특징은 "버튼 하나의 스타일"이 디자인 도구, Sass, React, 웹 컴포넌트 어디서도 같은 원천 데이터에서 나온다는 점이다. white·g10·g90·g100, 4가지 공식 테마를 CSS 커스텀 속성으로 즉시 전환할 수 있고, 접근성 검증(AVT)이 릴리스 파이프라인에 내장돼 있다.

(저장소 carbon-design-system/carbon · 제작/관리 IBM · 라이선스 Apache-2.0 · @carbon/react 1.113.x-rc / @carbon/web-components 2.60.x-rc / @carbon/themes·icons·colors·layout·type 11.x-rc(패키지별 독립 버전) · 27개 패키지 Yarn 워크스페이스 + Lerna(independent) + Nx · scss 파일 1,100개+ / ts·tsx·js 파일 2,500개+ · 최신 커밋 2026-07-29)
목차
  1. 한 줄 정체 — Carbon은 무엇인가
  2. 왜 지금 다시 주목받는가
  3. 무엇을 해결하는가
  4. 전체 구조 — 27개 패키지 지도
  5. 핵심 설계·동작 원리
  6. 기술 스택 · 의존성
  7. 설치 · 요구사항
  8. 실제 사용 흐름
  9. 함정 · 오해 방지
  10. 대안 비교
  11. 정리 — 누가 쓰면 좋은가

1한 줄 정체 — Carbon은 무엇인가

한 문장으로: "IBM이 자기 제품 전체에 쓰려고 만든, 토큰부터 컴포넌트까지 다 갖춘 디자인 시스템 모노레포"

Carbon Design System은 웹사이트 하나가 아니라 패키지 27개짜리 모노레포다. 그 안에는 색상표(@carbon/colors), 간격·타이포 규칙(@carbon/layout, @carbon/type), 그리드(@carbon/grid), 아이콘(@carbon/icons), 그리고 이 모든 걸 "테마"로 묶는 @carbon/themes가 있고, 그 위에 React 버전(@carbon/react)표준 웹 컴포넌트 버전(@carbon/web-components)이 나란히 올라간다.

즉 Carbon은 "예쁜 컴포넌트 라이브러리"가 아니라, 디자인 결정(색·간격·글꼴 크기)을 데이터로 만들고, 그 데이터를 여러 프레임워크가 공유하게 만드는 파이프라인이다. 실제로 색상 값 하나는 JSON(DTCG 토큰) 한 곳에만 적혀 있고, 그것이 Sass 맵으로, 다시 CSS 커스텀 속성과 JS 상수로 자동 생성된다.

한 줄 비유

"물감 낱개"가 아니라 "국가 표준 색표 + 그 색으로 그린 부품 도안 세트"

일반 UI 라이브러리는 예쁜 버튼·모달을 낱개로 파는 물감 세트에 가깝다. Carbon은 다르다. 먼저 "이 파랑은 정확히 몇 번 파랑이다"라는 표준 색표(토큰)를 국가 표준처럼 확정하고, 그 표준 색표만 사용해 그린 버튼·모달·표·폼 도안 127종을 함께 내놓는다.

덕분에 디자이너가 그린 화면과 개발자가 짠 코드가 "같은 파랑"을 쓰는지 다툴 일이 없다. 문제는, 이 표준 색표를 내가 마음대로 다시 칠할 수는 없고 정해진 창구(테마 오버라이드)로만 바꿀 수 있다는 것 — 자유도보다 일관성을 우선하는 시스템이다.

2왜 지금 다시 주목받는가

토큰 기반 디자인 시스템의 재부상 · AI가 만드는 화면의 "기준점" · v12 준비

Carbon은 신생 트렌드 저장소가 아니다. 10년 가까이 이어져 온 성숙한 엔터프라이즈 디자인 시스템이다. 그런데도 최근 다시 자주 언급되는 데는 세 가지 맥락이 있다.

① "토큰 우선(token-first)" 흐름의 표준 사례

Figma·Style Dictionary 등 디자인 툴 생태계가 DTCG(Design Tokens Community Group) 포맷으로 수렴하는 중인데, Carbon은 이미 white.json·g10.json·g90.json·g100.json 같은 실제 DTCG 토큰 파일을 Sass/JS로 컴파일하는 파이프라인을 운영 중이다. "토큰 기반 디자인 시스템을 실전 규모로 보고 싶다"는 사람들에게 Carbon은 몇 안 되는 완전히 공개된 실물 예시다.

② AI가 화면을 생성하는 시대의 "기준 부품함"

LLM 코딩 에이전트가 프론트엔드를 즉석에서 생성하는 일이 흔해지면서, 일관된 접근성·다크테마·간격 규칙을 이미 갖춘 컴포넌트 라이브러리의 가치가 오히려 커졌다. shadcn/ui 같은 "코드 복사형" 라이브러리와 달리 Carbon은 토큰 계층이 있는 "정책형" 시스템이라서, AI가 생성한 화면도 회사 표준에서 벗어나지 않게 잡아주는 역할을 한다. IBM 자체도 watsonx 등 생성형 AI 제품 UI를 Carbon 위에 짓는다.

③ v11 안에서 이미 시작된 v12 준비

저장소에는 docs/working-with-v12.md라는 별도 가이드가 있고, v12는 새 브랜치가 아니라 v11 코드베이스 안에서 feature flag(enable-v12-release)로 개발되고 있다. React·웹 컴포넌트 양쪽에 별도 포트의 v12 전용 Storybook(:3012, :6012)까지 마련돼 있어, "다음 메이저 버전을 어떻게 안전하게 준비하는가"를 보여주는 사례로도 주목받는다.

경쟁 지형에서의 위치
"자유로운 커스터마이징" 쪽이 아니라 "일관성·규모" 쪽

Tailwind 기반의 자유분방한 시스템들과 정반대 극단에 있다고 보면 이해가 빠르다. Carbon은 "이 회사(혹은 이 제품군) 전체가 같은 색·같은 리듬을 쓰게 강제"하는 데 최적화됐다. 그 대가로 개별 화면의 개성이나 가벼움은 상대적으로 덜 중요하게 취급한다.

3무엇을 해결하는가

"팀마다 다른 파랑" 문제 · 접근성 재작업 · 다크테마 이중 유지보수 · 프레임워크 이원화

큰 조직이 여러 팀에서 각자 UI를 만들면 반드시 벌어지는 문제들이 있다. Carbon은 그 문제들을 정면으로 겨냥해 설계됐다.

문제 ①

"팀마다 조금씩 다른 파랑, 조금씩 다른 여백"

디자이너와 개발자가 각자 감으로 색·간격을 정하면 제품군 전체가 미묘하게 어긋난다. Carbon은 spacing01~spacing13, background·text-primary 같은 이름 있는 토큰으로 이 결정을 한 곳에 고정하고, 코드에서는 값이 아니라 이름을 쓰게 강제한다.

문제 ②

제품마다 다시 하는 접근성 검증

버튼·모달·표를 새로 만들 때마다 키보드 포커스·ARIA·명도 대비를 처음부터 검증하는 건 비효율적이다. Carbon 컴포넌트는 이미 IBM의 3단계 접근성 검증(AVT1/2/3)을 통과한 상태로 배포되므로, 그 검증 비용을 팀마다 반복하지 않아도 된다.

문제 ③

라이트/다크 테마를 손으로 두 벌 유지보수

많은 프로젝트가 다크모드를 "나중에 CSS 뒤집어서" 대응하다 깨진다. Carbon은 처음부터 white·g10·g90·g100 4개 테마를 토큰 레벨에서 병렬로 정의해, 컴포넌트 코드는 그대로 두고 테마만 갈아 끼우면 전부 대응되게 만든다.

문제 ④

"React 팀"과 "표준 웹 팀"의 UI 이원화

사내에 React 앱도 있고 Vue/Angular나 순수 HTML 프로젝트도 있으면 UI 라이브러리를 두 벌 만들게 된다. Carbon은 같은 Sass 스타일(@carbon/styles)을 React 컴포넌트와 Lit 기반 웹 컴포넌트가 함께 가져다 쓰게 해, 프레임워크가 달라도 화면이 갈라지지 않게 한다.

4전체 구조 — 27개 패키지 지도

토큰 원천(색·간격·타입) → 테마 합성 → 스타일(Sass) → 프레임워크 구현(React·웹 컴포넌트)

packages/ 아래 27개 패키지가 있지만, 의존 방향을 따라가면 4개 층으로 요약된다.

┌──────────────────────────────────────────────────────────────────┐ │ CARBON 패키지 의존 방향 (아래 → 위로 소비) │ └──────────────────────────────────────────────────────────────────┘ [층 1] 원자 토큰 패키지 — 색·간격·타입·모션·그리드 @carbon/colors (색상 스케일) @carbon/layout (spacing01~13) @carbon/type (IBM Plex 타입셋) @carbon/motion (모션 커브) @carbon/grid (2x Grid 계산) @carbon/icons (SVG 아이콘 원본) │ 依存(dependency) ▼ [층 2] 테마 합성 — @carbon/themes src/dtcg/{white,g10,g90,g100}.json ← 사람이 편집하는 원천(DTCG) │ tasks/builders/dtcg-*.js 로 컴파일 ▼ scss/generated/themes/*.scss + js/generated/themes/*.js │ [층 3] 컴포넌트 스타일 — @carbon/styles scss/components/<이름>/_*.scss (버튼·모달·표 등 70여 개 컴포넌트 스타일) @forward '@carbon/themes' 로 테마·토큰을 그대로 흡수 │ ├──────────────┬────────────────────────┐ ▼ ▼ ▼ [층 4-A] [층 4-B] [층 4-C] @carbon/react @carbon/web-components carbon-components-react (TSX, 127개+ (Lit 커스텀 엘리먼트, (레거시 호환 패키지, React 로직만) button.scss 직접 import) v10 마이그레이션용)

핵심은 "층 3(스타일)까지는 프레임워크 중립"이고, 층 4에서만 React냐 웹 컴포넌트냐가 갈린다는 것이다. 실제로 @carbon/react의 배포용 index.scss는 이렇게 돼 있다.

// packages/react/index.scss (빌드 시 자동 생성, "DO NOT EDIT" 주석 포함)
@forward '@carbon/styles';

@carbon/react자기 스타일을 새로 만들지 않고 @carbon/styles를 그대로 재수출(re-export)한다. 웹 컴포넌트 쪽 버튼(src/components/button/button.scss)도 마찬가지로 같은 @carbon/styles 계층을 가져다 쓴다 — React 버전과 웹 컴포넌트 버전이 "따로 그려진 두 가지 버튼"이 아니라 같은 도안(Sass)을 각자 언어로 조립한 결과라는 뜻이다.

용어
DTCG (Design Tokens Community Group) 포맷
디자인 토큰을 { "$type": "color", "$value": "{gray.80}" } 같은 표준 JSON 구조로 적는 W3C 커뮤니티 규격. Carbon은 white/g10/g90/g100 테마를 이 포맷의 JSON 파일로 원천 관리하고, 여기서 Sass·JS를 자동 생성한다.
용어
모노레포 · Yarn 워크스페이스 · Lerna
여러 패키지를 한 저장소에 두고 함께 관리하는 방식. Carbon은 Yarn 워크스페이스로 27개 패키지를 묶고, Lerna를 "independent" 모드로 써서 패키지마다 서로 다른 버전 번호를 허용한다(모두 같은 버전으로 안 맞춤).

5핵심 설계 · 동작 원리

토큰 컴파일 파이프라인 · 4테마 커스텀 속성 · 2x Grid · 기능 플래그로 v12 트렁크 개발

설계 ① — "JSON 토큰 → Sass 맵 → CSS 커스텀 속성"이라는 3단 변환

Carbon 색상 체계의 진짜 원천은 사람이 손으로 고치는 packages/themes/src/dtcg/white.json 같은 DTCG JSON 파일이다. 이 안에는 다음처럼 토큰 간 참조(alias)가 담겨 있다.

{
  "background": {
    "$type": "color",
    "$value": "{white.default}",
    "$description": "전체 페이지 기본 배경색"
  },
  "background-inverse": {
    "$type": "color",
    "$value": "{gray.80}"
  }
}

이 JSON은 tasks/builders/dtcg-themes.js·dtcg-js-themes.js 같은 빌더를 거쳐 scss/generated/themes/js/generated/themes/컴파일된다. 이후 _theme.scsstheme() 믹스인이 이 맵을 순회하며 CSS 커스텀 속성(--cds-background 같은 변수)으로 뿌린다.

// packages/themes/scss/_theme.scss (요지)
@mixin theme($active-theme: $theme, $component-tokens...) {
  @each $token, $value in $active-theme {
    @include -custom-property($token, $value);  // --cds-{token}: {value};
  }
}

이 구조 덕분에 테마 전환이 CSS 재컴파일 없이 이뤄진다. 어떤 요소에 g100 테마의 커스텀 속성 값을 다시 뿌리기만 하면, 그 요소 아래 모든 컴포넌트가 즉시 다크 테마로 바뀐다. "값을 바꾸는 게 아니라, 같은 이름표(--cds-background)가 가리키는 실제 값만 바꾼다"는 것이 핵심이다.

비유

전등 스위치와 배선을 떠올리면 쉽다. 벽에 붙은 스위치 이름표는 "거실 조명"으로 고정돼 있고(=CSS 커스텀 속성 이름), 그 뒤에 어떤 전구(=실제 색상 값)를 연결할지는 계량기함(=테마 맵)에서 통째로 바꿀 수 있다. 전등(컴포넌트)은 배선을 새로 깔지 않아도 계량기함만 바뀌면 새 밝기로 켜진다.

설계 ② — white·g10·g90·g100, 4개 공식 테마

테마성격
white순백 배경 + 최고 대비의 라이트 테마. 텍스트 대비가 가장 뚜렷해 정보 밀도 높은 화면에 적합
g10연한 회색 배경의 라이트 테마. white보다 대비가 부드러워 시각적 피로를 줄인 버전
g90어두운 회색 계열 다크 테마
g100거의 검정에 가까운 다크 테마. 다크 테마 중 최고 대비

네 테마 모두 background·text-primary 같은 동일한 토큰 이름 집합을 갖고 값만 다르다. 그래서 컴포넌트 Sass·React 코드는 "지금이 무슨 테마인지" 전혀 몰라도 되고, 오직 --cds-* 커스텀 속성만 참조한다 — 테마 독립성이라 부르는 이 원칙이 Carbon 전체를 관통한다.

설계 ③ — 2x Grid: "필요한 변경만 내보내는" CSS 커스텀 속성 그리드

Carbon 그리드는 cds--grid·cds--row·cds--col 세 클래스로 구성되고, breakpoint(sm/md/lg/xlg/max)마다 컬럼 수·거터·마진을 CSS 커스텀 속성으로 노출한다. 흥미로운 점은 @carbon/grid의 믹스인이 "이전 breakpoint와 값이 달라졌을 때만" 새 규칙을 내보내도록 짜여 있다는 것 — 불필요한 CSS 중복을 스스로 줄이는 설계다.

:root {
  --cds-grid-gutter: #{$grid-gutter};
  --cds-grid-columns: /* 가장 작은 breakpoint 값 */;
  --cds-grid-margin: /* 가장 작은 breakpoint 값 */;
}
/* 이후 breakpoint는 "직전과 다를 때만" 재정의 */

설계 ④ — 기능 플래그 하나로 Sass·JS·React·웹 컴포넌트 4개 층을 동시에 통제

packages/feature-flags/feature-flags.yml에 등록된 플래그 하나(예: enable-v12-release)가 다음 4곳에서 동시에 인식된다.

그리고 enable-v12-release가 켜지면 enable-v12-로 시작하는 다른 모든 플래그가 자동으로 함께 켜지는 규칙까지 있다. 이 메커니즘 위에서 Carbon v12는 별도 브랜치가 아니라 v11 메인 코드베이스 안에서, 플래그로 가려진 채로 개발되고 있다 — React·웹 컴포넌트 양쪽에 v12 전용 Storybook 포트(3012/6012)까지 따로 준비해 미리보기만 분리한 상태다.

설계 ⑤ — AVT(Accessibility Verification Testing) 3단계가 CI에 내장

Carbon 컴포넌트는 만들어지면 끝이 아니라 AVT1(자동 검증) → AVT2(수동: 키보드·화면 확대) → AVT3(스크린 리더 확인) 3단계를 거친다. 저장소에는 achecker.js(IBM의 accessibility-checker 설정)와 *-test.avt.e2e.js 패턴의 Playwright 테스트가 80개 가까이 있으며, CI에서 자동 실행된다.

설계상 중요한 경계
패키지마다 버전 번호가 다르다 — "Carbon 버전"은 하나의 숫자가 아니다

Lerna를 independent 모드로 쓰기 때문에, 실제로 @carbon/react1.113.x, @carbon/web-components2.60.x, @carbon/themes·icons·colors·layout·type11.x대로 서로 다른 메이저 번호를 갖는다.

"Carbon v11" 같은 마케팅 명칭은 디자인 시스템의 세대를 가리키는 것이지, npm의 package.json 버전과 1:1로 대응하지 않는다. 의존성 설치 시 패키지별 버전을 각각 확인해야 한다.

6기술 스택 · 의존성

Yarn 워크스페이스 + Lerna(independent) + Nx · Sass + TypeScript + Lit · Storybook·Jest·Playwright
영역구성
모노레포 관리Yarn 워크스페이스(workspaces: ["actions/*","config/*","packages/*"]) + Lerna(version: independent, 버전·릴리스 관리) + Nx(targetDefaults.build.dependsOn: ["^build"], 빌드 캐시·순서 관리)
스타일 원천Sass(SCSS) 1,100개+ 파일. @carbon/styles가 모든 컴포넌트 스타일의 단일 창구
React 구현TypeScript + React(peer, React 19대 대응), @carbon/react에 127개+ 컴포넌트 디렉터리, Storybook MDX 문서 동봉
웹 컴포넌트 구현Lit 기반 커스텀 엘리먼트(@carbon/web-components), @lit/context·@floating-ui/dom 사용
토큰 빌드DTCG JSON → tasks/builders/dtcg-*.js(Babel/Node 스크립트) → 생성된 Sass·JS. @carbon/scss-generator·내부 @carbon/cli로 번들링
테스트Jest(단위) + Playwright(e2e, *.vrt.e2e.js 시각 회귀 + *.avt.e2e.js 접근성) + accessibility-checker(IBM aChecker 계열)
문서/탐색Storybook(React용 :3011, 웹 컴포넌트용 :6011, v12 프리뷰는 :3012/:6012)
품질 도구ESLint 9 + typescript-eslint + Stylelint(Sass 린트) + Prettier + Husky(Git hook) + commitlint
사용 통계@ibm/telemetry-js — 각 패키지 postinstall에서 실행돼 익명 사용 지표를 IBM 서버로 전송(9절 참고)
용어
Lit
구글이 만든 경량 웹 컴포넌트 프레임워크. 프레임워크 종속 없이 브라우저 표준 커스텀 엘리먼트(<cds-button> 등)를 만들 수 있게 해준다. Carbon 웹 컴포넌트 구현체의 기반이다.
용어
Nx
모노레포의 빌드 순서·캐시를 관리하는 도구. Carbon은 targetDefaults로 "패키지 A를 빌드하기 전에 A가 의존하는 패키지들을 먼저 빌드(^build)"하도록 강제한다.

7설치 · 요구사항

Node 20+ (엔진 기준) · 저장소 개발은 Node 24 고정 · 대형 모노레포 클론 시간 고려
용도방법
제품에 컴포넌트 쓰기npm install @carbon/react react react-dom (또는 @carbon/web-components만 단독 설치)
Node 버전루트 package.jsonengines.node>=20.x, 저장소 자체 개발/CI는 .nvmrc24.18.0 고정
스타일 로딩번들러(Webpack/Vite 등)에 Sass 컴파일 설정이 있어야 함 — JS 컴포넌트만 설치해서는 스타일이 적용되지 않는다(9절 함정 참고)
서체타입 토큰은 IBM Plex 계열(Sans/Serif/Mono/Sans Condensed 등)을 기본값으로 가정 — 별도로 폰트를 로드해야 실제 타이포가 IBM Plex로 보인다
저장소 직접 클론git cloneyarn install → 27개 패키지가 함께 설치되므로 대형 모노레포 특유의 긴 설치 시간·큰 node_modules를 감수해야 함
로컬 탐색cd packages/react && yarn storybook(포트 3011) / cd packages/web-components && yarn storybook(포트 6011)로 컴포넌트 카탈로그 확인
주의
"가벼운 라이브러리"가 아니다

Carbon은 디자인 시스템 전체를 제공하는 만큼 번들 크기·학습 곡선이 작지 않다. 버튼 하나 쓰자고 전체를 들이는 대신, 실제로 여러 화면·여러 팀에 걸친 일관성이 필요한 상황인지 먼저 판단해야 한다.

8실제 사용 흐름

설치 → 스타일 임포트 → 테마 적용 → 그리드로 레이아웃 → 컴포넌트 조립 → Storybook으로 API 확인

1단계 — 패키지 설치와 스타일 임포트

npm install @carbon/react react react-dom 후, 앱 전역 스타일 파일에서 반드시 @use '@carbon/react/index.scss';(또는 필요한 컴포넌트 scss만 선택 임포트)를 해야 한다. JS 컴포넌트 import만으로는 겉모습이 나오지 않는다.

2단계 — 테마 지정

<Theme theme="g100">(React) 또는 최상위 요소에 대응하는 클래스/속성을 지정해 white·g10·g90·g100 중 하나를 활성화한다. 이 시점에 --cds-* 커스텀 속성이 그 테마 값으로 채워진다.

3단계 — 그리드로 레이아웃 뼈대 잡기

<Grid><Column sm={4} md={8} lg={16}>...</Column></Grid> 형태로 breakpoint별 컬럼 폭을 지정한다. 내부적으로 cds--grid/cds--col-* 클래스와 CSS 커스텀 속성이 동작한다.

4단계 — 컴포넌트 조립

import { Button, DataTable, Modal } from '@carbon/react' 형태로 필요한 컴포넌트를 가져와 조합한다. 웹 컴포넌트 프로젝트라면 import '@carbon/web-components/es/components/button/index.js' 후 HTML에 <cds-button> 태그를 직접 쓴다.

5단계 — Storybook·MDX 문서로 실제 props 확인

각 컴포넌트 폴더에는 *.mdx 문서와 *.stories.js가 함께 있다. 저장소를 직접 클론했다면 yarn storybook으로 실행해 실제 소스가 반영된 props 표와 예제를 즉시 확인할 수 있다 — 공식 사이트 문서보다 로컬 Storybook이 더 최신 소스에 가깝다.

기여(contribute) 흐름

포크 → yarn install → 원하는 패키지 디렉터리(예: packages/react)에서 yarn test(Jest) / e2e는 루트에서 yarn test:e2e(Playwright, AVT·VRT 포함) → PR 제출. 접근성에 영향을 주는 변경은 AVT 테스트 통과가 사실상 필수다.

9함정 · 오해 방지

Sass 임포트 빠뜨림 · 버전 번호 헷갈림 · IBM 브랜드 자산 착각 · 설치 시 텔레메트리
함정 ①
JS만 설치하고 Sass를 안 붙이면 "스타일 없는 컴포넌트"만 남는다

@carbon/react의 컴포넌트 로직(TSX)과 스타일(Sass)은 물리적으로 분리된 파일이다. import { Button } from '@carbon/react'만 하고 @carbon/react/index.scss를 임포트하지 않으면, 기능은 동작하는데 디자인은 하나도 적용되지 않은 맨 HTML 버튼처럼 보인다. 처음 접하는 사람이 가장 자주 겪는 "왜 예제랑 다르게 생겼지" 문제다.

함정 ②
"Carbon v11"이라는 말과 npm 버전 숫자를 동일시하면 안 된다

5절에서 다뤘듯 @carbon/react1.x, @carbon/web-components2.x, @carbon/themes11.x다. "Carbon 11을 쓴다"는 말이 곧 @carbon/react@11을 의미하지 않는다 — 패키지별로 package.json을 직접 확인해야 한다.

함정 ③
코드는 Apache-2.0이지만 "IBM"이라는 이름·이미지는 별개다

이 저장소의 소스 코드 자체는 Apache-2.0 라이선스로 자유롭게 재사용·수정·재배포할 수 있다. 다만 그렇다고 해서 IBM 로고, "IBM" 브랜드 명칭, IBM 제품처럼 보이는 마케팅 표현까지 자유롭게 가져다 써도 된다는 뜻은 아니다. Carbon을 기반으로 만든 제품이 IBM의 후원·제휴를 받은 것처럼 보이지 않도록 별도로 주의해야 한다.

함정 ④
설치 시 조용히 도는 사용 통계 수집(postinstall telemetry)

여러 Carbon 패키지의 package.json에는 "postinstall": "ibmtelemetry --config=telemetry.yml"이 있다. @ibm/telemetry-js가 설치 시 실행되어 어떤 props를 어떤 이름으로 썼는지 같은 익명 사용 지표를 IBM 서버로 전송한다. 폐쇄망·오프라인 CI 환경에서는 이 단계가 실패하거나 예기치 않은 네트워크 호출로 보일 수 있다.

함정 ⑤
React판과 웹 컴포넌트판은 "같은 스타일, 다른 구현체" — 기능이 항상 동시에 나오진 않는다

두 구현체가 같은 @carbon/styles를 공유해 겉모습은 같지만, 컴포넌트 로직 자체는 각각 따로 유지보수된다. 새 컴포넌트나 신규 prop이 한쪽(대개 React)에 먼저 나오고 다른 쪽은 나중에 따라오는 경우가 흔하다.

용어
커스터마이징 난도
토큰 값은 손으로 직접 고치는 게 아니라 DTCG JSON → 빌드 파이프라인을 거쳐 생성되므로, 색 하나를 바꾸려면 저장소를 포크해 소스를 고치기보다 @include theme($my-theme)처럼 내 프로젝트 쪽에서 테마 맵을 오버라이드하는 방식이 권장된다. "왜 색이 하드코딩되어 있지 않지?"에서 오는 초기 혼란이 흔하다.

10대안 비교

Material UI(MUI) · Microsoft Fluent UI · Adobe Spectrum · Shopify Polaris
시스템소속/성격스타일 기반프레임워크 범위어울리는 용도
CarbonIBM · 엔터프라이즈 지향Sass + CSS 커스텀 속성(DTCG 토큰)React + 표준 웹 컴포넌트(Lit) 병행다수 팀·다수 제품에 걸친 일관성, 강한 접근성 요구
Material UI(MUI)구글 Material 스펙의 커뮤니티/상업 구현CSS-in-JS(Emotion)React 중심Material 룩앤필을 빠르게 쓰고 싶은 React 프로젝트
Fluent UI마이크로소프트 · Office/Teams 계열CSS-in-JS + 자체 토큰React 중심(웹), 별도 네이티브 구현MS 생태계 제품, Office 톤의 UI
SpectrumAdobe · 크리에이티브 툴 지향React Aria 기반 + 자체 토큰React(React Spectrum) 중심고밀도 작업 도구, 강한 상호작용 커스터마이징
PolarisShopify · 커머스 지향CSS + 토큰React 중심Shopify 앱/어드민류 커머스 UI

Carbon을 다른 시스템과 가르는 가장 뚜렷한 축은 "React 전용이 아니라 표준 웹 컴포넌트까지 1급으로 지원"한다는 점과, 토큰 원천이 DTCG JSON으로 완전히 공개돼 있고 4개 공식 테마가 처음부터 병렬 설계돼 있다는 점이다. 반대로 MUI·Spectrum류는 React 생태계 안에서의 개발 속도·컴포넌트 다양성에 좀 더 강점이 있다.

11정리 — 누가 쓰면 좋은가

일관성·접근성·다크테마가 정책 수준으로 필요한 조직에 적합, 개성 있는 소규모 프로젝트엔 과함

Carbon은 "디자인 결정을 데이터(토큰)로 굳히고, 그 데이터를 여러 프레임워크가 공유하게 만드는" 성숙한 엔터프라이즈 디자인 시스템이다. 색 하나, 간격 하나까지 이름 붙여 관리하고, 그 위에 접근성 검증까지 마친 React·웹 컴포넌트 두 구현체를 함께 제공한다.

이런 경우 강력 추천
여러 팀·여러 제품이 같은 룩앤필을 지켜야 하는 조직

사내 관리자 도구, 여러 제품군을 가진 B2B SaaS, 정부·금융·헬스케어처럼 접근성 컴플라이언스가 필수인 프로덕트, 그리고 React와 순수 웹 표준(웹 컴포넌트) 둘 다 써야 하는 조직에 특히 잘 맞는다. 다크/라이트 테마 전환을 처음부터 정책으로 요구받는 팀에도 적합하다.

이런 경우엔 신중히
강한 브랜드 개성이 필요하거나, 아주 가벼워야 하는 프로젝트

마케팅 랜딩 페이지처럼 남과 다른 룩앤필이 경쟁력인 프로젝트, 혹은 번들 크기·초기 학습 곡선을 극도로 줄여야 하는 소규모 프로젝트에는 Carbon 전체를 들이는 것이 과할 수 있다. 이런 경우 필요한 토큰·컴포넌트만 선별해서 쓰거나, 더 가벼운 시스템을 검토하는 편이 낫다.