콘텐츠로 이동
Study Noteshadcn/ui

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 파일. 이름은 프로젝트마다 다를 수 있다. 이 파일이 곧 테마다.
  1. 프로젝트를 만든다

    터미널 창
    pnpm create next-app@latest my-app
    cd my-app

    Tailwind CSS 설치 여부를 물으면 예라고 답한다.

  2. shadcn/ui를 붙인다

    터미널 창
    pnpm dlx shadcn@latest init
  3. 컴포넌트를 받는다

    터미널 창
    pnpm dlx shadcn@latest add button card input
  4. 쓴다

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

전제 조건 두 가지 — Tailwind가 설치돼 있을 것, @/* 경로 별칭이 있을 것. create-next-app이 둘 다 해준다. 기존 프로젝트에 붙이는 거라면 이 둘을 먼저 확인한다.

shadcn init이 components.json·globals.css·lib/utils.ts·package.json 네 곳을 건드리는 것을 보여주는 그림
파일하는 일이 덱에서
components.json이후 모든 CLI 동작의 기준이 장
app/globals.css토큰 정의 = 테마 본체4~10장 전부
lib/utils.tscn() — 클래스 이름을 합치는 도우미7장
의존성clsx, tailwind-merge, class-variance-authority, 프리미티브, 아이콘7·8장

init 직후 파일의 뼈대는 이렇다. 세 덩어리로 읽으면 된다.

app/globals.css
@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 몇 줄

필드만 나중에 바꿔서는 전환되지 않는다. 이미 받은 컴포넌트의 클래스는 그대로라, 전환하려면 CLI v4의 preset 재적용이나 재설치 후 diff를 검토해야 한다.

앱 화면 대부분을 차지하는 중립색 계열이다. 현재 선택지는 neutral · stone · zinc · mauve · olive · mist · taupe다. 차이는 미묘하지만 인상은 꽤 다르다 — 4장에서 실물로 비교한다. 이것도 components.json의 값만 고쳐서는 기존 토큰과 컴포넌트가 바뀌지 않는다.

add로 받은 파일이 어디에 생길지 정한다. 기본값이면 components/ui/다. 이건 나중에 바꿔도 된다 (이미 받은 파일을 옮기는 건 손으로 해야 하지만).

필드한 줄바꿀 수 있나
style기반 라이브러리와 시각 프리셋의 조합preset 재적용 필요
rsctrue면 필요한 파일에 "use client" 자동 추가✅
tsxfalse면 .jsx로 생성✅
tailwind.prefix유틸리티 클래스에 접두사 (tw- 등)✅
registries외부 레지스트리 등록 (11장)✅
  • components.json CLI 설정. git에 커밋한다
  • 디렉터리app/
    • globals.css 테마 본체 — 이 덱의 주 무대
    • layout.tsx 폰트와 다크 모드 설정이 들어갈 곳 (8·9장)
  • 디렉터리lib/
    • utils.ts cn() 하나뿐인 파일
  • 디렉터리components/
    • 디렉터리ui/ shadcn이 관리하는 영역 — 손대는 규칙이 필요하다
      • button.tsx
      • card.tsx
      • input.tsx
    • 직접 만든 컴포넌트는 여기, ui/ 밖에 둔다

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가 필요한데, 이건 내 수정이 날아간다는 뜻이다.)

  • init이 만드는 것 넷: components.json · globals.css 토큰 · lib/utils.ts · 의존성
  • globals.css가 테마 본체다. 세 덩어리 — Tailwind 불러오기 / 값 정의 / @theme inline 연결
  • components.json에서 실제로 중요한 것은 cssVariables(이 덱에서는 true) · baseColor · aliases
  • cssVariables·baseColor·style은 필드만 고쳐서는 기존 코드가 전환되지 않는다
  • Tailwind 4는 tailwind.config.js를 안 쓴다 — CSS 안의 @theme이 대신한다
  • components/ui/와 직접 만든 컴포넌트를 섞지 않는다
  • 자주 쓰는 명령: view · add · --dry-run · --diff · search