콘텐츠로 이동

14. 설치와 구조

init에서 고르는 것 중 셋은 나중에 못 바꾼다

  1. Next.js 프로젝트

    Terminal window
    pnpm create next-app@latest my-app
    cd my-app
  2. shadcn/ui 초기화

    Terminal window
    pnpm dlx shadcn@latest init
  3. 첫 컴포넌트

    Terminal window
    pnpm dlx shadcn@latest add button
  4. 쓴다

    app/page.tsx
    import { Button } from '@/components/ui/button'
    export default function Home() {
    return <Button>클릭</Button>
    }

전제 조건 두 가지: Tailwind가 설치돼 있을 것, tsconfig.json@/* alias가 있을 것. create-next-app이 둘 다 해준다.

  1. components.json 생성 — 이후 모든 CLI 동작의 기준이 된다
  2. lib/utils.ts 생성cn() 함수 (11장)
  3. globals.css 수정 — 토큰(:root, .dark)과 @theme inline 블록 추가
  4. 의존성 설치clsx, tailwind-merge, class-variance-authority, 프리미티브
  5. 아이콘 라이브러리 설치 — 기본은 lucide

3번이 12장에서 본 그 토큰 블록이다. init 직후 globals.css를 열어보면 학습 효과가 크다.

{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"ui": "@/components/ui",
"utils": "@/lib/utils",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
필드 의미 나중에 바꿀 수 있나
style 컴포넌트의 시각적 성격 불가
rsc true면 필요한 파일에 use client 자동 추가 가능
tsx false면 .jsx로 생성 가능
tailwind.config v4에서는 빈 문자열
tailwind.css 토큰을 주입할 CSS 파일 경로 가능
tailwind.baseColor 중립색 계열 불가
tailwind.cssVariables true면 의미 토큰, false면 유틸리티 직접 불가
tailwind.prefix 유틸리티 접두사 (tw- 등) 가능
aliases.* 파일이 놓일 위치 가능
registries 외부 레지스트리 등록 가능

이 선택이 이 덱 전체에서 가장 중요한 설정 하나다.

<div className="bg-background text-foreground">
  • 다크 모드가 공짜 (12장)
  • 테마 교체가 변수 몇 줄 (17장)
  • 컴포넌트에 원시 색이 없다

앱의 90%를 차지하는 회색 계열이다. 미묘하지만 인상 차이가 크다.

계열 성격
zinc 완전 중립. 가장 무난하다
slate 푸른 기. 차분하고 테크틱
stone 따뜻한 기. 부드러움
neutral 순수 무채색
mauve / olive / mist / taupe 미세한 색조가 섞인 중립색

브랜드 색이 따뜻하면 stone/taupe, 차가우면 zinc/mist 쪽이 어울린다.

예전에는 defaultnew-york 둘뿐이었다. 지금은 여덟 가지다.

스타일 성격
vega / nova 예전 new-york 계열. 조밀하고 그림자 위주
maia / lyra / mira 코어 라인업
luma 2026년 3월 추가
rhea luma를 더 조밀하게. 밀도 높은 제품 화면용
sera 타이포 중심. 세리프 제목 + 각진 모서리 + 밑줄 컨트롤

--style 플래그나 shadcn/create에서 고른다. 나중에 못 바꾸므로 프로젝트 시작 전에 웹사이트에서 실물을 비교해 보는 게 좋다.

flowchart TD
    I["shadcn init"] --> A{"cssVariables"}
    A -->|"true ✅"| OK["토큰 기반<br/>테마 교체 가능"]
    A -->|"false ❌"| BAD["하드코딩 색<br/>17장 불가"]
    I --> B["baseColor 선택<br/>zinc · slate · stone …"]
    I --> C["style 선택<br/>8가지"]
    B --> L["🔒 나중에 못 바꿈"]
    C --> L
    OK --> L2["🔒 나중에 못 바꿈"]

    classDef ok   fill:#dcfce7,stroke:#16a34a,color:#14532d
    classDef bad  fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
    classDef warn fill:#fef3c7,stroke:#d97706,color:#78350f
    classDef mute fill:#f1f5f9,stroke:#94a3b8,color:#334155
    class OK ok
    class BAD bad
    class L,L2 warn
    class I,A,B,C mute
명령 하는 일
init / create 프로젝트 설정 · 새 프로젝트 생성
add [name…] 컴포넌트 추가
view [name…] 설치 전에 소스를 미리 본다
search / list 레지스트리에서 검색·목록
docs [name] 컴포넌트 문서·API 조회
info 현재 프로젝트 설정 확인
build registry.json → 배포용 JSON 생성 (16장)
migrate 아이콘 교체, RTL, radix 통합 패키지 전환
apply / preset 프리셋(테마 등) 적용 (17장)
eject shadcn 유틸을 인라인화하고 의존성 제거 (되돌릴 수 없음)
Terminal window
# 설치 전에 소스 확인
pnpm dlx shadcn@latest view button
# 무엇이 바뀔지만 보고 실행 안 함
pnpm dlx shadcn@latest add dialog --dry-run
# 내가 수정한 파일과 최신 버전의 차이
pnpm dlx shadcn@latest add button --diff
# 수정본을 덮어쓰기 (주의)
pnpm dlx shadcn@latest add button --overwrite
# 전부 설치
pnpm dlx shadcn@latest add --all
# 특정 경로에
pnpm dlx shadcn@latest add card --path components/shared
Terminal window
pnpm dlx shadcn@latest add dialog
✔ Created 3 files:
- components/ui/dialog.tsx
- components/ui/button.tsx ← dialog가 필요로 해서
- hooks/use-media-query.ts ← 함께
✔ Installed 1 package:
- @base-ui-components/react
  • registryDependencies가 다른 레지스트리 항목을 가리킨다
  • dependencies는 npm 패키지를 가리킨다
  • 이미 있는 파일은 덮어쓰지 않는다 (--overwrite 없이는)
  • components.json CLI의 기준. git에 커밋한다
  • 디렉터리app/
    • globals.css 토큰. 여기가 디자인 시스템의 뿌리
  • 디렉터리lib/
    • utils.ts cn()
  • 디렉터리components/
    • 디렉터리ui/ shadcn이 관리하는 영역
      • button.tsx
      • card.tsx
      • dialog.tsx

이 네 가지가 앞으로 계속 나온다. 특히 globals.csscomponents/ui/가 이 스택의 자산이 쌓이는 곳이다.

Terminal window
pnpm dlx shadcn@latest init --monorepo
  • 디렉터리apps/
    • 디렉터리web/
      • components.json "ui": "@workspace/ui/components"
    • 디렉터리admin/
      • components.json
  • 디렉터리packages/
    • 디렉터리ui/
      • components.json 컴포넌트가 실제로 사는 곳
      • 디렉터리src/components/
      • src/styles/globals.css 토큰도 여기
  • 컴포넌트와 토큰은 packages/ui 한 곳에만 둔다
  • 각 앱은 그걸 import만 한다
  • add를 앱에서 실행해도 파일은 packages/ui에 생긴다
  • initcomponents.json · lib/utils.ts · globals.css 토큰 · 의존성을 만든다
  • cssVariables: true는 반드시 켠다. 나중에 못 바꾸고, 테마 교체가 불가능해진다
  • stylebaseColor나중에 못 바꾼다 — 시작 전에 실물을 비교한다
  • 기본 베이스는 Base UI, -b radix로 Radix 선택 가능
  • view(미리보기), --dry-run, --diff(수정 추적)를 기억한다
  • 모노레포는 packages/ui에 컴포넌트와 토큰을 모은다