콘텐츠로 이동
Study Noteshadcn/ui

1. shadcn/ui란 무엇인가

UI 컴포넌트를 통째로 제공하는 런타임 패키지를 설치하는 방식이 아니다. CLI는 실행하지만, 컴포넌트 소스는 내 레포에 들어온다.

이 장에서 처음 나오는 말4개
컴포넌트 라이브러리Component Library
버튼·모달 같은 UI 부품을 모아 놓은 패키지. Material UI, Ant Design, Chakra 등. 설치하면 node_modules 에 들어간다.
프리미티브Primitive / Headless Component
겉모습 없이 동작만 들어 있는 부품. 키보드 조작, 포커스 이동, 화면낭독기 대응처럼 눈에 안 보이지만 직접 만들면 지옥인 부분을 담당한다.
레지스트리Registry
컴포넌트 소스를 JSON 형식으로 담아 둔 배포처. shadcn CLI가 여기서 코드를 받아 내 레포에 복사한다.
a11y / 접근성Accessibility
키보드만으로 쓸 수 있는가, 화면낭독기가 읽을 수 있는가. a 와 y 사이에 글자가 11개라 a11y라 줄여 쓴다.

먼저 없으면 무슨 문제가 생기는지부터 보자. 전통적인 컴포넌트 라이브러리를 쓰면 이런 일이 생긴다.

import { Button } from 'some-ui-library'
<Button>저장</Button>

디자이너가 “버튼 모서리를 좀 더 각지게, 그림자는 빼 주세요”라고 한다. 그런데 —

  • 그 스타일은 node_modules 안에 있다. 직접 고치면 재설치 때 사라지므로 공식 확장 API 안에서만 바꾸는 게 안전하다
  • 라이브러리가 열어 준 theme 설정으로 되는 범위까지만 가능하다
  • 안 되면 !important로 덮어쓰기 시작한다
  • 다음 버전으로 올리면 내부 클래스 이름이 바뀌어 덮어쓴 것들이 깨진다

복사돼 온 button.tsx 하나가 렌더하는 것이 이렇다 — variant(성격)와 size(크기)라는 두 축이 독립적으로 조합된다.

variant="default"
variant="secondary"
variant="destructive"
variant="outline"
variant="ghost"
variant="link"
size="sm"
size="default"
size="lg"
size="icon"
disabled
:focus-visible

“그냥 복붙이랑 뭐가 다른가”

섹션 제목: ““그냥 복붙이랑 뭐가 다른가””

정당한 질문이다. 실제로 초기에는 복붙과 비슷했고, 지금은 네 가지가 다르다.

하는 일없으면
레지스트리컴포넌트를 JSON으로 정의된 배포 단위로 관리어느 버전을 복사했는지 알 수 없다
의존성 해결add dialog 하면 필요한 button도 함께빠뜨린 파일을 찾아 헤맨다
토큰 주입컴포넌트가 쓰는 CSS 변수를 globals.css에 자동 추가색이 안 나오고 원인을 모른다
경로 조정내 프로젝트 폴더 구조에 맞게 import 경로를 고쳐서 넣어 준다import 경로를 전부 손으로 고친다

그리고 --diff 명령이 있다. 내가 고친 파일과 최신 원본의 차이를 보여준다 — 복붙에는 이게 없다. (11장)

shadcn/ui 컴포넌트는 스타일만 들어 있는 게 아니다. 동작과 접근성은 아래층의 프리미티브가 담당한다.

앱이 내 레포의 ui 파일을 거쳐 npm 프리미티브로, 다시 브라우저로 내려가는 층 구조

소유권을 넘겨받는 건 노란 층뿐이다. 파란 층은 여전히 npm 패키지다 — 그게 다행이다.

모달 창 하나를 직접 만든다고 해보자. 눈에 보이는 것은 “어두운 배경 + 흰 상자”가 전부지만, 제대로 동작하려면 아래가 전부 필요하다.

  • 열리면 포커스가 모달 안으로 들어가야 한다
  • Tab을 계속 눌러도 모달 밖으로 빠져나가면 안 된다 (포커스 트랩)
  • Esc로 닫혀야 한다
  • 닫히면 원래 있던 버튼으로 포커스가 돌아가야 한다
  • 화면낭독기가 “대화 상자”라고 읽도록 role="dialog", aria-modal 이 붙어야 한다
  • 뒤 배경은 스크롤되면 안 된다

이걸 전부 직접 유지보수하고 싶은 사람은 없다. 그래서 이 부분만은 패키지로 남겨 둔다.

얻는 것

디자인 변경에 제약이 없다. 컴포넌트 코드를 읽고 이해할 수 있다. 안 쓰는 코드는 지워도 된다. 새 버전이 로컬 UI 코드를 자동 교체하지 않는다. 팀 컴포넌트로 자연스럽게 확장된다.

지는 책임

버그 수정이 자동으로 오지 않는다. 접근성 개선도 자동이 아니다. 팀원이 제각각 고치면 일관성이 무너진다. 어떤 파일을 고쳤는지 추적해야 한다. 새로 온 사람에게 “우리 규칙”을 알려줘야 한다.

오른쪽은 시간이 해결해 주지 않는다. 관리 구조를 의도적으로 만들어야 하고, 그 구조가 바로 이 덱이 말하는 테마다. 그래서 다음 장이 테마다.

  • 디자인을 고칠 일이 없다 — 사내 관리도구, 데모, 프로토타입. 완성품 라이브러리가 더 빠르다
  • 엑셀 같은 복합 위젯이 당장 필요하다 — 데이터 그리드, 간트 차트는 전문 라이브러리를 산다
  • Tailwind를 쓰지 않는다 — 이점의 절반이 사라진다
  • 프론트엔드를 계속 볼 사람이 없다 — 소유권은 곧 유지보수 인력이다

반대로 디자인이 계속 진화하고 UI 코드를 관리할 팀이 있는 제품이라면 이 모델의 장점이 크다.

  • shadcn/ui는 코드 배송 시스템이다. UI 전체를 런타임 패키지로 받지 않고 소스를 가져온다
  • 컴포넌트 소스가 내 레포(components/ui/)에 들어오고, 그때부터 내 코드다
  • 복붙과 다른 점: 레지스트리 · 의존성 해결 · 토큰 주입 · 경로 조정, 그리고 --diff
  • 키보드·포커스·화면낭독기 대응은 프리미티브(기본값 Base UI)가 계속 맡는다
  • 자유를 얻는 대신 버그 수정이 자동으로 오지 않는 책임을 진다
  • 그 책임을 감당하는 구조가 테마다