글 검색

제목으로 글을 찾습니다

디자인 시스템 구축 가이드 — 구성요소와 shadcn과 AI 도구

2026-01-15#design-system#shadcn#ai

디자인 시스템의 구성요소는 세가지로 볼수있따. 이셋을 만드는 것과 shadcn/ui 위에 얹는 구체적인 방법, 그리고 AI 도구가 시스템을 지키게 만드는 설정까지 정리했다.

예를들어보자 버튼을 블루 계열의 색상으로 만들때 화면마다 미묘하게 다르다면? 누군가 #3182F6을 복사했고, 누군가는 #3B82F6을 썼다. 모달은 세 명이 세 번 만들어서 세가지의 버전으로 있다면? 이 상태를 끝내는 도구가 디자인 시스템이다. 정의는 간단하다 — 같은 UI 결정을 두 번 하지 않기 위한 장치.

디자인 시스템의 구성요소 세 가지#

디자인 시스템은 보통 세 개의 층으로 정리한다. KRDS(대한민국 정부 디자인 시스템)나 LINE 디자인 시스템 같은 공개 사례들도 같은 구조다.

  1. 원칙(Principles) — 판단 기준. "무엇이 우리다운 화면인가"에 대한 답을 문장으로 적은 것. "위험한 작업은 반드시 한 번 더 확인받는다" 같은 문장.
  2. 파운데이션(Foundations) — 디자인 언어의 최소 단위. 색, 타이포그래피, 간격, 모서리 라운드, 아이콘. 코드에서는 이 값들에 이름을 붙인 디자인 토큰이 된다 — #3182F6이 아니라 --primary.
  3. 컴포넌트(Components) — 파운데이션을 조립해 만든 재사용 UI. Button, Input, Dialog.

파운데이션 없는 컴포넌트는 색을 하드코딩하고, 컴포넌트 없는 파운데이션은 쓸 곳이 없고, 원칙 없는 시스템은 같은 컴포넌트를 사람마다 다르게 쓴다.

원칙(Principles)#

원칙이라고 해서 브랜드 철학 문서를 쓰는 게 아니다. 팀이 UI를 놓고 의견이 갈릴 때 판정 기준이 되는 문장 몇 개면 충분하다.

  • 한 화면에 강조 버튼은 하나만 둔다.
  • 삭제·결제처럼 되돌릴 수 없는 작업은 확인 단계를 거친다.
  • 본문 텍스트는 최소 14px. 줄이지 않는다.

이 문장들이 있어야 뒤에서 만들 파운데이션과 컴포넌트에 "왜"가 생긴다. destructive variant가 존재하는 이유가 곧 두 번째 문장이다.

파운데이션(Foundations)#

파운데이션의 값들을 코드로 옮기는 형식이 디자인 토큰이고, 가장 검증된 방법은 primitive와 semantic 두 단계로 나누는 것이다.

:root {
  /* primitive — 값 자체. 팔레트를 나열한다 */
  --blue-500: #3182f6;
  --red-500: #f04452;
  --gray-100: #f2f4f6;
 
  /* semantic — 용도. primitive를 참조한다 */
  --primary: var(--blue-500);
  --destructive: var(--red-500);
  --muted: var(--gray-100);
}

컴포넌트는 semantic만 쓴다. 이 한 겹의 간접 참조가 주는 이점은 아주 많다. 브랜드 색을 파랑에서 초록으로 바꾼다고 가정하면, 고치는 곳은 --primary: var(--green-500) 한 줄이다. 화면 200개를 뒤져야 했을수도 있는게 CSS 한 줄이 된다.

토큰 이름은 디자이너의 Figma variables와 글자까지 똑같이 맞추는게 좋다. Figma에 primary가 있으면 코드에도 --primary다. 이름이 같아야 "여기 primary로 바꿔주세요"라는 소통또한 자연스럽게 이루어진다.

컴포넌트(Components)#

컴포넌트를 컨트롤할때는 boolean prop 조합이 아니라 속성props의 속성값으로 만든다.

속성값은 디자이너와 함께 정하는게 좋다. 디자이너가 "고스트 버튼" 이라고 부르면 코드도 ghost인것이다. 이 목록이 곧 팀의 어휘가 된다.

만드는 순서는 사용 빈도순이다. Button → Input → Select → Dialog. 전체 목록을 다 갖추고 나서 쓰기 시작하는 게 아니라, 하나가 완성되면 그 하나부터 실제 화면에 투입한다.

원칙은 코드와 같이 세팅해둔다.#

원칙과 사용 규칙을 별도 위키에만 쓰면 아무도 안 읽는다. 원칙은 코드에서 가장 가까운에 있어야한다. — 주석, 레포의 README, 그리고 뒤에서 다룰 AI 규칙 파일. "위험한 작업의 확인 버튼은 destructive", "한 화면에 default 버튼은 하나만" 처럼 원칙을 컴포넌트의 언어로 번역한 문장이면 충분하다.

이 셋을 shadcn 위에 얹기#

shadcn/ui는 요즘 React 프로젝트에서 사실상 표준이 된 컴포넌트 도구다. npm 패키지가 아니라서 설치 방식이 다르다 — npx shadcn add button을 실행하면 버튼의 소스 코드가 내 레포의 components/ui/button.tsx로 복사된다. 의존성이 아니라 내 코드가 된다.

이 구조가 디자인 시스템과 잘 맞는 이유는, 위에서 말한 세 요소가 전부 수정 가능한 파일로 손에 들어오기 때문이다.

파운데이션은 이렇게 넣는다 — shadcn은 --background, --primary, --destructive 같은 semantic 변수 체계를 이미 갖고 있고, 모든 컴포넌트가 이 변수만 참조한다. 할 일은 globals.css에서 이 변수들에 우리 팔레트를 채우는 것이다. 위의 2단계 토큰 구조가 그대로 들어간다.

컴포넌트는 이렇게 고친다button.tsx를 열면 cva로 선언된 variant 목록이 있다.

const buttonVariants = cva('...', {
  variants: {
    variant: {
      default: 'bg-primary text-primary-foreground',
      destructive: 'bg-destructive text-white',
      outline: 'border bg-background',
      // 우리 디자인에 없는 variant는 지우고,
      // 필요한 variant는 여기 추가한다
    },
  },
})

npm 라이브러리였다면 wrapper를 만들고 스타일을 덮어쓰는 작업이지만, shadcn에서는 그냥 내 파일을 수정하는 일이다. 지운 variant는 팀 누구도 못 쓴다 — 닫힌 목록이 강제된다.

다른 프로젝트에는 이렇게 나눠준다 — 프로젝트가 여러 개라면 다듬은 컴포넌트를 레지스트리로 배포할 수 있다. 레포에 registry.json을 정의해두면 다른 프로젝트에서 npx shadcn add @our-org/button으로 설치한다. 공용 npm 패키지의 빌드·버저닝 작업 없이 배포 경로가 생긴다.

AI 도구가 시스템을 지키게 만들기#

Cursor, Claude Code 같은 AI 코딩 도구는 레포의 코드를 읽고 거기 있는 패턴을 따라 쓴다. shadcn 컴포넌트는 패키지 안에 있지 않고 레포안의 파일이라서 AI가 전부 읽을 수 있다. 즉 디자인 시스템이 코드로 존재하면, AI의 결과물도 시스템을 따른다. 이걸 확실하게 만드는 설정이 세 가지 있다.

1. AI 규칙 파일에 시스템을 명시한다. Claude Code는 CLAUDE.md, Cursor는 .cursorrules를 읽는다. 원칙과 사용 규칙을 여기에 적으면 모든 AI 세션이 그 규칙 아래서 코드를 쓴다.

## UI 규칙
- 색상은 semantic 변수만 사용한다. hex 값 하드코딩 금지.
- 버튼은 components/ui/button.tsx를 사용한다.
  새 버튼 컴포넌트를 만들지 않는다.
- variant 추가가 필요하면 buttonVariants에 추가하고
  디자이너 리뷰를 받는다.

2. 토큰 밖의 값을 lint로 차단한다. AI도 사람처럼 lint에 걸린다. text-[#3182f6] 같은 arbitrary value를 ESLint 규칙으로 막아두면, AI가 규칙 파일을 무시하고 hex를 쓰더라도 CI에서 잡힌다. 규칙 파일이 "권고"라면 lint는 "강제"다.

3. 레지스트리를 AI에 연결한다. shadcn 레지스트리는 MCP(Model Context Protocol) 서버로 노출할 수 있다. 연결해두면 AI 도구가 "우리 조직에 어떤 컴포넌트가 있는지"를 직접 조회하고, 새로 만드는 대신 add 명령으로 설치한다. 사내 컴포넌트가 있는 줄 몰라서 또 만드는 문제 — 사람도 AI도 똑같이 겪는 그 문제가 막힌다.

요약#

  • 디자인 시스템 = 원칙 + 파운데이션 + 컴포넌트. 셋 다 있어야 작동한다.
  • 원칙은 판정 기준 문장 몇 개, 파운데이션은 primitive/semantic 두 단계 토큰, 컴포넌트의 variant는 닫힌 목록. 원칙은 코드 옆에 두고, 컴포넌트는 사용 빈도순으로 만든다.
  • shadcn은 이 셋을 전부 내 레포의 파일로 소유하게 해준다. 토큰은 globals.css, variant는 cva 선언, 배포는 레지스트리.
  • AI 도구에는 규칙 파일로 알려주고, lint로 강제하고, 레지스트리를 연결한다. 코드로 존재하는 시스템만 AI가 지킨다.