Claude Code for Front-end #1: CLAUDE.md 작성 가이드

728x90

Claude Code와 대화하는 법 - AI에게 프로젝트를 설명하는 가장 효과적인 방법


1️⃣ 들어가며

Claude Code에게 "회원가입 페이지 만들어줘"라고 요청했을 때 두 가지 상황이 벌어집니다.

상황 A: "어떤 필드가 필요하신가요? 어떤 상태 관리 라이브러리를 쓰시나요? 스타일링은 어떻게 하시나요?"

상황 B: "React Hook Form과 Zod로 이메일/비밀번호/비밀번호 확인 필드를 만들었습니다. Zustand로 인증 상태를 관리하고 Tailwind로 스타일링했습니다."

차이는 단 하나, CLAUDE.md 파일의 존재 여부입니다.


2️⃣ CLAUDE.md가 필요한 이유

AI 코딩 도구의 핵심은 "컨텍스트"


Claude Code는 대화할 때마다 프로젝트의 맥락을 파악해야 합니다. CLAUDE.md는 프로젝트의 설명서로, 한 번 작성하면 Claude Code는 모든 대화에서 이 정보를 참고합니다.

Claude Code는 세션을 시작할 때 다음 순서로 컨텍스트를 구성합니다:

1. 전역 설정 로드: ~/.claude/ 디렉토리의 공통 규칙

2. 프로젝트 설정 파싱: CLAUDE.md 읽기 및 분석

3. 환경 정보 수집: Git 상태, 파일 구조, 의존성

4. 컨텍스트 통합: 우선순위에 따른 규칙 병합

이 과정에서 CLAUDE.md는 프로젝트별 컨텍스트의 단일 진실 공급원(Single Source of Truth)으로 작동합니다.

매번 설명하는 것 vs 한 번 작성하는 것

CLAUDE.md 없이 작업할 때:

개발자: "API 호출 함수 만들어줘"
Claude: "어떤 HTTP 클라이언트를 사용하시나요?"
개발자: "axios요"
Claude: "base URL은 어디에 있나요?"
개발자: ".env에 API_URL이요"
Claude: "에러 처리는 어떻게 하시나요?"
개발자: "try-catch로 하고 toast로 보여줘요"

CLAUDE.md 작성 후

개발자: "API 호출 함수 만들어줘"
Claude: "axios 인스턴스 사용해서 POST 요청 함수를 만들었습니다.
        에러는 try-catch로 처리하고 toast로 사용자에게 보여줍니다."

실제 비교 사례

같은 요청, 다른 결과:

// CLAUDE.md 없을 때
async function fetchData(id: string) {
    // TODO: implement API call
    throw new Error("Not implemented")
}

// CLAUDE.md 있을 때
async function fetchData(id: string) {
    try {
        const response = await apiClient.get(`/items/${id}`)
        return response.data
    } catch (error) {
        toast.error("데이터를 불러오는데 실패했습니다.")
        throw error
    }
}

3️⃣ 기본 구조 잡기

CLAUDE.md는 5개 핵심 섹션으로 구성합니다.

1. 프로젝트 개요 (Project Overview)

프로젝트의 정체성을 한눈에 보여줍니다.

## Project Overview

This is a web application built with modern React ecosystem.

**Tech Stack**:

-   Framework: Next.js 15.0.0 with App Router
-   Language: TypeScript 5.3
-   Package Manager: pnpm 8.9.0
-   State Management: Zustand + TanStack Query
-   Styling: Tailwind CSS
-   Form: React Hook Form + Zod

필수 정보:

  • 프레임워크 및 버전 (API 호환성에 필수)
  • 언어 및 타입 시스템
  • 패키지 매니저
  • 주요 라이브러리

기술적 중요성: 버전 정보는 API 호환성, 기능 가용성, 마이그레이션 경로 결정에 필수적입니다.

2. 디렉토리 구조 (Directory Structure)

Claude가 파일을 어디에 만들어야 하는지 판단할 수 있게 합니다.

## Directory Structure

src/
├── app/
│ ├── (pages)/ # Route groups (괄호는 라우팅 제외용 그룹 폴더를 의미)
│ │ ├── [id]/ # Dynamic routes
│ │ └── page.tsx # Route pages
│ ├── (shared)/ # Shared components
│ ├── api/ # API routes (route.ts)
│ └── layout.tsx # Root layout
├── components/ # Reusable components
├── lib/ # Utilities
└── types/ # Type definitions

### Directory Naming Rules

-   `(name)/`: Route groups - URL에 포함되지 않음
-   `[param]/`: Dynamic route segments
-   `_name/`: Private folders - 라우팅에서 제외

### Directory Roles

-   `(pages)/`: Route group for page components
-   `(shared)/`: Shared resources across the app
-   `api/`: Next.js API routes (route.ts files)
-   `components/`: Reusable UI components

Before:

개발자: "UserProfile 컴포넌트 만들어줘"
Claude: "어디에 만들까요?"

After:

개발자: "UserProfile 컴포넌트 만들어줘"
Claude: "src/components/user/UserProfile.tsx에 생성했습니다"

설계 원칙:

  • 실제 디렉토리 구조와 동기화 유지
  • 특수 폴더 규칙 명시 (route groups, dynamic segments)
  • 각 디렉토리의 역할 1줄 설명

3. 코드 컨벤션 (Code Conventions)

일관된 코드 스타일을 유지합니다.

## Code Conventions

### Naming Rules

-   **Components**: PascalCase (`UserCard.tsx`, `DashboardLayout.tsx`)
-   **Pages**: 항상 `page.tsx` (Next.js App Router)
-   **Layouts**: 항상 `layout.tsx` (Next.js App Router)
-   **API Routes**: 항상 `route.ts` (Next.js App Router)
-   **Utilities**: camelCase (`formatDate.ts`, `apiClient.ts`)
-   **Hooks**: `use` prefix (`useAuth.ts`, `useDebounce.ts`)
-   **Types**: PascalCase with suffix (`UserData.types.ts`)
-   **Constants**: UPPER_SNAKE_CASE (`API_BASE_URL`, `MAX_RETRY_COUNT`)

### TypeScript Guidelines

**Type vs Interface 선택 기준:**

-   ✅ `interface`: 객체 shape 정의, 확장 가능한 구조
-   ✅ `type`: Union, Intersection, Utility types, Tuple, Function types

**규칙:**

-   **Never use `any`** - use `unknown` with type guards
-   Always define prop types for components
-   Use explicit return types for functions

### Examples

\```typescript
// ❌ Bad
function getData(): any {
return fetch('/api/data')
}

// ✅ Good
interface ApiResponse {
data: User[]
total: number
}

async function getData(): Promise<ApiResponse> {
const response = await fetch('/api/data')
return response.json()
}
\```

### Prohibited Patterns

-   ❌ **No `any` type** - Use specific types or `unknown`
-   ❌ **No TODO comments** - Complete implementations only
-   ❌ **No inline styles** - Use Tailwind classes
-   ❌ **No magic numbers** - Define as constants
-   ❌ **No console.log** - Use proper logging utility

적용 기준:

  • ESLint 규칙과 동기화
  • Prettier 설정 반영
  • 프레임워크 권장사항 준수

4. 개발 명령어 (Essential Commands)

Claude가 직접 명령어를 실행할 수 있게 합니다.

## Essential Commands

### Development
```bash
pnpm dev              # Run dev server (port 3000)
pnpm dev:turbo        # Run with Turbopack
```

### Build & Quality Checks
```bash
pnpm build            # Production build
pnpm lint             # ESLint check
pnpm format           # Prettier formatting
pnpm test             # Run tests
pnpm typecheck        # TypeScript check
```

### Package Management
```bash
pnpm install              # Install dependencies
pnpm add [package]        # Add package
pnpm add -D [package]     # Add dev dependency
```

자주 사용하는 명령어만 선별하세요. 모든 명령어를 나열할 필요는 없습니다.

5. 실용적 예제 (Common Patterns)

자주 만드는 패턴을 템플릿화합니다.

## Common Patterns

### Client Component with State
```typescript
'use client'

import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'

export function UserList() {
  const { data, isLoading } = useQuery({
    queryKey: ['users'],
    queryFn: fetchUsers,
  })

  if (isLoading) return <div>Loading...</div>

  return (
    <ul>
      {data?.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}
```

### API Client Pattern
```typescript
// lib/apiClient.ts
import axios from 'axios'

export const apiClient = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL,
  headers: {
    'Content-Type': 'application/json',
  },
})

apiClient.interceptors.request.use((config) => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})
```

### React Query Mutation
```typescript
// api/user.mutation.ts
import { useMutation } from '@tanstack/react-query'
import { apiClient } from '@/lib/apiClient'

export const useCreateUser = () => {
  return useMutation({
    mutationFn: async (data: CreateUserRequest) => {
      const response = await apiClient.post('/users', data)
      return response.data
    },
    onSuccess: () => {
      toast.success('생성되었습니다')
    },
    onError: (error) => {
      toast.error('생성에 실패했습니다')
    }
  })
}
```

4️⃣ 작성 후 테스트하기

Claude Code에게 질문해보기

CLAUDE.md를 작성한 후 실제로 테스트해보세요.

테스트 질문 1: "새로운 페이지를 만들려면 어디에 파일을 생성해야 해?"
기대 응답: "src/app/(pages)/ 디렉토리에 page.tsx 파일을 생성하면 됩니다."

테스트 질문 2: "API 호출은 어떻게 해야 해?"
기대 응답: "apiClient를 사용하고 React Query의 useMutation을 활용하세요."

테스트 질문 3: "개발 서버 실행 명령어는?"
기대 응답: "pnpm dev 명령어로 개발 서버를 실행할 수 있습니다."

테스트 질문 4: "컴포넌트 파일명은 어떻게 지어?"
기대 응답: "PascalCase로 작성합니다. 예: UserCard.tsx"

테스트 질문 5: "any 타입 사용해도 돼?"
기대 응답: "any 타입은 사용 금지입니다. unknown이나 구체적인 타입을 사용하세요."

응답 품질 확인 체크리스트

  • 올바른 디렉토리를 제안하는가?
  • 프로젝트의 코딩 스타일을 따르는가?
  • 사용하는 라이브러리를 올바르게 적용하는가?
  • 명령어를 정확하게 실행하는가?
  • 금지 패턴을 피하는가?

구문 검증

마크다운 구문을 검증합니다:

# markdownlint를 사용한 린팅
npx markdownlint-cli CLAUDE.md

# 또는 VS Code 확장 프로그램 사용
# markdownlint extension by David Anson

5️⃣ 완성 템플릿

다음은 바로 복사해서 사용할 수 있는 CLAUDE.md 템플릿입니다.

# CLAUDE.md

This file provides guidance to Claude Code when working with this repository.

## Project Overview

This is a **[프로젝트 유형]** built with:
- **Framework**: [Next.js 15 / React / Vue]
- **Language**: TypeScript
- **Package Manager**: [pnpm / npm / yarn]
- **State Management**: [Zustand / Recoil / Redux]
- **Styling**: [Tailwind CSS / styled-components]
- **Form**: [React Hook Form / Formik]

## Directory Structure

```
src/
├── app/              # [설명]
├── components/       # [설명]
├── lib/             # [설명]
└── types/           # [설명]
```

### Directory Roles
- `app/`: [역할 설명]
- `components/`: [역할 설명]
- `lib/`: [역할 설명]

## Code Conventions

### Naming Rules
- **Components**: PascalCase (`UserCard.tsx`)
- **Utilities**: camelCase (`formatDate.ts`)
- **Constants**: UPPER_SNAKE_CASE (`API_BASE_URL`)

### TypeScript Guidelines
- Never use `any` type
- Prefer interfaces over types
- Define prop types for all components

### Prohibited Patterns
- ❌ TODO comments
- ❌ console.log
- ❌ Inline styles

## Essential Commands

### Development
```bash
[dev command]          # Run dev server
[build command]        # Production build
[test command]         # Run tests
```

### Package Management
```bash
[install command]      # Install dependencies
[add command]          # Add new package
```

## Common Patterns

### Component Template
```typescript
[자주 사용하는 컴포넌트 패턴]
```

### API Call Pattern
```typescript
[API 호출 패턴]
```

### State Management
```typescript
[상태 관리 패턴]
```


6️⃣ 정리

CLAUDE.md는 프로젝트와 AI 사이의 공통 언어입니다.

핵심 체크리스트

  • [ ] 프로젝트 개요 작성 (기술 스택, 버전)
  • [ ] 디렉토리 구조 설명 (파일 위치 가이드)
  • [ ] 코드 컨벤션 명시 (네이밍, 패턴, 금지사항)
  • [ ] 개발 명령어 정의 (dev, build, lint, test)
  • [ ] 실용적 예제 포함 (자주 쓰는 패턴)
  • [ ] 작성 후 테스트 (질문으로 검증)

효과

  • 반복 설명 제거 → 개발 시간 단축
  • 일관된 코드 품질 유지
  • 팀원 온보딩 시간 감소
  • AI와의 협업 효율 극대화

베스트 프랙티스

  1. 정기적 업데이트: 프로젝트 진화에 따라 CLAUDE.md 동기화
  2. 실제 사용 기반: 팀이 실제로 따르는 규칙만 문서화
  3. 구체적 예시: 추상적 설명보다 코드 예시 선호
  4. 버전 명시: 의존성 버전 명확히 기록

30분 투자로 수십 시간의 반복 설명을 절약할 수 있습니다. 지금 바로 프로젝트 루트에 CLAUDE.md를 만들어보세요.

반응형