콘텐츠로 이동
Study Note프론트엔드

14. 설치와 구조

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

  1. Next.js 프로젝트

    터미널 창
    pnpm create next-app@latest my-app
    cd my-app
  2. shadcn/ui 초기화

    터미널 창
    pnpm dlx shadcn@latest init
  3. 첫 컴포넌트

    터미널 창
    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컴포넌트의 시각적 성격불가
rsctrue면 필요한 파일에 use client 자동 추가가능
tsxfalse면 .jsx로 생성가능
tailwind.configv4에서는 빈 문자열—
tailwind.css토큰을 주입할 CSS 파일 경로가능
tailwind.baseColor중립색 계열불가
tailwind.cssVariablestrue면 의미 토큰, false면 유틸리티 직접불가
tailwind.prefix유틸리티 접두사 (tw- 등)가능
aliases.*파일이 놓일 위치가능
registries외부 레지스트리 등록가능

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

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

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

계열성격
zinc완전 중립. 가장 무난하다
slate푸른 기. 차분하고 테크틱
stone따뜻한 기. 부드러움
neutral순수 무채색
mauve / olive / mist / taupe미세한 색조가 섞인 중립색
zinc — 완전 중립 · 가장 무난
50
100
200
300
400
500
600
700
800
900
950
slate — 푸른 기 · 차분하고 테크틱
50
100
200
300
400
500
600
700
800
900
950
stone — 따뜻한 기 · 부드러움
50
100
200
300
400
500
600
700
800
900
950

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

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

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

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

shadcn init에서 cssVariables·baseColor·style 선택이 나중에 못 바꾸는 결정으로 이어지는 갈래
명령하는 일
init / create프로젝트 설정 · 새 프로젝트 생성
add [name…]컴포넌트 추가
view [name…]설치 전에 소스를 미리 본다
search / list레지스트리에서 검색·목록
docs [name]컴포넌트 문서·API 조회
info현재 프로젝트 설정 확인
buildregistry.json → 배포용 JSON 생성 (16장)
migrate아이콘 교체, RTL, radix 통합 패키지 전환
apply / preset프리셋(테마 등) 적용 (17장)
ejectshadcn 유틸을 인라인화하고 의존성 제거 (되돌릴 수 없음)
터미널 창
# 설치 전에 소스 확인
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
터미널 창
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.css와 components/ui/가 이 스택의 자산이 쌓이는 곳이다.

터미널 창
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에 생긴다
  • init은 components.json · lib/utils.ts · globals.css 토큰 · 의존성을 만든다
  • cssVariables: true는 반드시 켠다. 나중에 못 바꾸고, 테마 교체가 불가능해진다
  • style과 baseColor도 나중에 못 바꾼다 — 시작 전에 실물을 비교한다
  • 기본 베이스는 Base UI, -b radix로 Radix 선택 가능
  • view(미리보기), --dry-run, --diff(수정 추적)를 기억한다
  • 모노레포는 packages/ui에 컴포넌트와 토큰을 모은다