3. 테마가 놓이는 자리
파일 네 개만 알면 된다. 그중 하나가 테마다.
이 장에서 처음 나오는 말4개
`init`Initialize- 프로젝트에 shadcn/ui를 처음 붙이는 명령. 설정 파일과 토큰을 만들어 준다. 프로젝트당 한 번.
`dlx`Download & Execute- 패키지를 설치하지 않고 한 번만 실행하는 pnpm 명령. npm의
npx, yarn의dlx와 같다. shadcn CLI는 설치할 필요가 없어 이 방식으로 쓴다. alias / 경로 별칭Path Alias../../../components/ui/button대신@/components/ui/button으로 쓰게 해 주는 설정.tsconfig.json에 정의한다.`globals.css`- Tailwind를 불러오고 토큰을 정의하는 CSS 파일. 이름은 프로젝트마다 다를 수 있다. 이 파일이 곧 테마다.
처음부터 끝까지
섹션 제목: “처음부터 끝까지”-
프로젝트를 만든다
터미널 창 pnpm create next-app@latest my-appcd my-appTailwind CSS 설치 여부를 물으면 예라고 답한다.
-
shadcn/ui를 붙인다
터미널 창 pnpm dlx shadcn@latest init -
컴포넌트를 받는다
터미널 창 pnpm dlx shadcn@latest add button card input -
쓴다
app/page.tsx import { Button } from '@/components/ui/button'export default function Home() {return <Button>클릭</Button>}
전제 조건 두 가지 — Tailwind가 설치돼 있을 것, @/* 경로 별칭이 있을 것.
create-next-app이 둘 다 해준다. 기존 프로젝트에 붙이는 거라면 이 둘을 먼저 확인한다.
init이 만드는 것 네 개
섹션 제목: “init이 만드는 것 네 개”| 파일 | 하는 일 | 이 덱에서 |
|---|---|---|
components.json | 이후 모든 CLI 동작의 기준 | 이 장 |
app/globals.css | 토큰 정의 = 테마 본체 | 4~10장 전부 |
lib/utils.ts | cn() — 클래스 이름을 합치는 도우미 | 7장 |
| 의존성 | clsx, tailwind-merge, class-variance-authority, 프리미티브, 아이콘 | 7·8장 |
globals.css — 여기가 테마다
섹션 제목: “globals.css — 여기가 테마다”init 직후 파일의 뼈대는 이렇다. 세 덩어리로 읽으면 된다.
@import "tailwindcss"; /* ① Tailwind 불러오기 */
:root { /* ② 라이트 값 */ --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0); /* … 20개 남짓 */}
.dark { /* ② ' 다크 값 — 같은 이름 */ --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --primary: oklch(0.922 0 0); --primary-foreground: oklch(0.205 0 0);}
@theme inline { /* ③ Tailwind에 연결 */ --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --radius-lg: var(--radius);}- ②가 “무슨 값인가” — 테마마다 바뀐다. 브랜드 색 교체는 여기만 고친다
- ③이 “어떤 클래스를 만들 것인가” — 한 번 쓰고 거의 안 건드린다
- ②만 있고 ③이 없으면 변수는 있는데
bg-primary클래스가 없다 (4장)
components.json — 실제로 중요한 필드 세 개
섹션 제목: “components.json — 실제로 중요한 필드 세 개”파일 전체는 이렇지만, 처음에 신경 쓸 것은 세 개다.
{ "$schema": "https://ui.shadcn.com/schema.json", "style": "base-nova", "rsc": true, "tsx": true, "tailwind": { "config": "", "css": "app/globals.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" }, "iconLibrary": "lucide", "aliases": { "components": "@/components", "ui": "@/components/ui", "utils": "@/lib/utils", "lib": "@/lib", "hooks": "@/hooks" }, "registries": {}}① cssVariables — 이 덱에서는 true
섹션 제목: “① cssVariables — 이 덱에서는 true”이 덱 전체에서 가장 중요한 설정 하나다.
<div className="bg-background text-foreground">- 컴포넌트에 의미 토큰만 들어간다
- 다크 모드가 값 교체로 해결된다
- 테마 교체가 CSS 몇 줄
<div className="bg-white text-zinc-950 dark:bg-zinc-950 dark:text-zinc-50">- 컴포넌트에 원시 색이 직접 박힌다
- 색을 쓰는 컴포넌트에 원시 색과
dark:변형이 반복된다 - 의미 토큰 기반의 일괄 테마 교체가 어려워진다
필드만 나중에 바꿔서는 전환되지 않는다. 이미 받은 컴포넌트의 클래스는 그대로라, 전환하려면 CLI v4의 preset 재적용이나 재설치 후 diff를 검토해야 한다.
② baseColor — 중립색 계열
섹션 제목: “② baseColor — 중립색 계열”앱 화면 대부분을 차지하는 중립색 계열이다. 현재 선택지는 neutral · stone · zinc ·
mauve · olive · mist · taupe다.
차이는 미묘하지만 인상은 꽤 다르다 — 4장에서 실물로 비교한다.
이것도 components.json의 값만 고쳐서는 기존 토큰과 컴포넌트가 바뀌지 않는다.
③ aliases — 파일이 놓일 위치
섹션 제목: “③ aliases — 파일이 놓일 위치”add로 받은 파일이 어디에 생길지 정한다. 기본값이면 components/ui/다.
이건 나중에 바꿔도 된다 (이미 받은 파일을 옮기는 건 손으로 해야 하지만).
나머지 필드
섹션 제목: “나머지 필드”| 필드 | 한 줄 | 바꿀 수 있나 |
|---|---|---|
style | 기반 라이브러리와 시각 프리셋의 조합 | preset 재적용 필요 |
rsc | true면 필요한 파일에 "use client" 자동 추가 | ✅ |
tsx | false면 .jsx로 생성 | ✅ |
tailwind.prefix | 유틸리티 클래스에 접두사 (tw- 등) | ✅ |
registries | 외부 레지스트리 등록 (11장) | ✅ |
파일 지도
섹션 제목: “파일 지도”- components.json CLI 설정. git에 커밋한다
디렉터리lib/
- utils.ts
cn()하나뿐인 파일
- utils.ts
디렉터리components/
디렉터리ui/ shadcn이 관리하는 영역 — 손대는 규칙이 필요하다
- button.tsx
- card.tsx
- input.tsx
- 직접 만든 컴포넌트는 여기, ui/ 밖에 둔다
CLI — 실제로 쓰는 명령
섹션 제목: “CLI — 실제로 쓰는 명령”70개 넘는 옵션이 있지만 일상적으로 쓰는 건 이 정도다.
# 설치 전에 소스를 미리 본다 — 가장 저평가된 명령pnpm dlx shadcn@latest view button
# 컴포넌트 추가pnpm dlx shadcn@latest add dialog
# 무엇이 바뀔지만 보고 실행은 안 함pnpm dlx shadcn@latest add dialog --dry-run
# 내가 고친 파일과 최신 원본의 차이 (11장의 핵심 도구)pnpm dlx shadcn@latest add button --diff
# 뭐가 있는지 찾기pnpm dlx shadcn@latest search @shadcn -q "table"
# 현재 프로젝트의 기반·style·설치 항목 확인pnpm dlx shadcn@latest info의존성은 자동으로 따라온다
섹션 제목: “의존성은 자동으로 따라온다”pnpm dlx shadcn@latest add dialog레지스트리 항목에 선언된 다른 컴포넌트와 npm 패키지가 있으면 CLI가 함께 해결한다.
정확히 무엇이 추가될지는 항목마다 다르므로 view나 --dry-run으로 먼저 확인한다.
기본 동작은 이미 있는 파일을 덮어쓰지 않는 것이다. 내가 고쳐 둔 파일은 그대로 남는다.
(강제로 덮어쓰려면 --overwrite가 필요한데, 이건 내 수정이 날아간다는 뜻이다.)
3장 요약
섹션 제목: “3장 요약”init이 만드는 것 넷:components.json·globals.css토큰 ·lib/utils.ts· 의존성globals.css가 테마 본체다. 세 덩어리 — Tailwind 불러오기 / 값 정의 /@theme inline연결components.json에서 실제로 중요한 것은cssVariables(이 덱에서는 true) ·baseColor·aliasescssVariables·baseColor·style은 필드만 고쳐서는 기존 코드가 전환되지 않는다- Tailwind 4는
tailwind.config.js를 안 쓴다 — CSS 안의@theme이 대신한다 components/ui/와 직접 만든 컴포넌트를 섞지 않는다- 자주 쓰는 명령:
view·add·--dry-run·--diff·search
참고 자료
섹션 제목: “참고 자료”- Next.js 설치 가이드 — 현재
init·add흐름과 전제 조건 components.json레퍼런스 — 각 필드의 의미와 초기화 뒤 변경 제약- CLI 레퍼런스 —
view·search·--dry-run·--diff의 정확한 문법