Claude Code 실전 (1): Context가 전부다
SOTA A-Z·

Claude Code 실전 (1): Context가 전부다
CLAUDE.md 하나로 AI 코딩 어시스턴트의 성능이 달라진다. 대규모 프로젝트에서 Claude가 길 잃지 않게 만드는 법.
TL;DR
- Context = 성능: Claude Code는 코드를 "읽는" 게 아니라 "이해"해야 함
- CLAUDE.md: 프로젝트의 뇌 역할, 컨벤션/구조/금기사항 명시
- 모노레포 전략: 서브 디렉토리별
.claude/활용으로 컨텍스트 분리 - 하지 말아야 할 것: 무엇을 하지 말라고 알려주는 게 더 중요할 때가 있다
1. 왜 Context인가?
같은 질문, 다른 결과
"이 프로젝트에 로그인 기능 추가해줘"
Context 없이:
// 어디에 둬야 할지 모름
// src/login.ts? pages/login.tsx? auth/index.js?
// 기존 스타일과 전혀 다른 코드 생성
// 이미 있는 유틸 함수 재작성Context 있으면:
// src/features/auth/에 생성 (기존 구조 따름)
// 프로젝트의 에러 핸들링 패턴 적용
// 기존 useAuth 훅 확장
// 팀 컨벤션에 맞는 네이밍Claude는 코드베이스를 "검색"할 수 있지만, 그것만으론 부족합니다.
팀의 결정, 암묵적 규칙, 아키텍처 의도는 코드만 봐서는 알 수 없습니다.
2. CLAUDE.md 작성법
위치와 우선순위
프로젝트/
├── CLAUDE.md # 루트 (전체 프로젝트)
├── packages/
│ ├── frontend/
│ │ └── CLAUDE.md # 프론트엔드 전용
│ └── backend/
│ └── CLAUDE.md # 백엔드 전용
└── .claude/
└── settings.json # Claude Code 설정Claude는 현재 작업 디렉토리부터 상위로 올라가며 모든 CLAUDE.md를 읽습니다.
핵심 섹션
1) 프로젝트 개요
# 프로젝트: E-commerce Platform
## 기술 스택
- Frontend: Next.js 14 (App Router), TypeScript, Tailwind
- Backend: Node.js, Prisma, PostgreSQL
- Infra: Vercel, AWS RDS
## 아키텍처
모노레포 구조. 프론트엔드와 백엔드가 분리되어 있으며,
공통 타입은 `packages/shared`에서 관리.2) 폴더 구조 설명
## 폴더 구조
src/
├── app/ # Next.js App Router 페이지
├── components/
│ ├── ui/ # 재사용 가능한 UI 컴포넌트 (Button, Input 등)
│ └── features/ # 기능별 컴포넌트 (ProductCard, CartItem 등)
├── hooks/ # 커스텀 훅
├── lib/ # 유틸리티, API 클라이언트
├── stores/ # Zustand 스토어
└── types/ # TypeScript 타입 정의3) 컨벤션 (매우 중요!)
## 코딩 컨벤션
### 네이밍
- 컴포넌트: PascalCase (ProductCard.tsx)
- 훅: camelCase with "use" prefix (useAuth.ts)
- 유틸: camelCase (formatPrice.ts)
- 상수: SCREAMING_SNAKE_CASE
### 컴포넌트 작성
- Props는 interface로 정의, ComponentNameProps 패턴
- 'use client'는 정말 필요할 때만
- 스타일은 Tailwind만 사용 (CSS 파일 생성 금지)
### 에러 처리
- API 호출은 반드시 try-catch
- 에러는 lib/errors.ts의 AppError 클래스 사용
- 사용자 메시지는 constants/messages.ts에서 가져오기4) 하지 말아야 할 것 (핵심!)
## ⛔ 금지 사항
### 절대 하지 마세요
- `any` 타입 사용 금지 (unknown 사용)
- console.log 커밋 금지 (logger 유틸 사용)
- 인라인 스타일 금지
- node_modules, .env 파일 수정 금지
### 주의 사항
- DB 스키마 변경 시 반드시 마이그레이션 파일 생성
- 새 의존성 추가 전 팀 논의 필요 (PNPM만 사용)
- API 엔드포인트 추가 시 OpenAPI 스펙 업데이트 필수5) 자주 쓰는 명령어
## 개발 명령어pnpm dev # 개발 서버 (포트 3000)
pnpm build # 프로덕션 빌드
pnpm test # Jest 테스트
pnpm lint # ESLint 검사
pnpm db:migrate # Prisma 마이그레이션
pnpm db:studio # Prisma Studio
3. 대규모 프로젝트에서의 Context 하이라이팅
문제: 모노레포에서 Claude가 길을 잃는다
monorepo/
├── apps/
│ ├── web/ # Next.js
│ ├── mobile/ # React Native
│ └── admin/ # Admin 대시보드
├── packages/
│ ├── ui/ # 공유 UI
│ ├── api-client/ # API 클라이언트
│ └── shared/ # 공통 타입/유틸
└── services/
├── auth/ # 인증 서비스
├── payment/ # 결제 서비스
└── notification/ # 알림 서비스10개 이상의 패키지, 수만 줄의 코드...
"web 앱에 기능 추가해줘"라고 하면 Claude가 엉뚱한 곳을 참조할 수 있습니다.
해결책 1: 서브 디렉토리별 CLAUDE.md
# apps/web/CLAUDE.md
## 이 패키지는?
Next.js 14 기반 메인 웹 애플리케이션.
B2C 고객용 쇼핑몰 프론트엔드.
## 의존하는 패키지
- @monorepo/ui: 공유 UI 컴포넌트
- @monorepo/api-client: API 호출
- @monorepo/shared: 타입 정의
## 이 패키지에서 작업할 때
- UI 컴포넌트 수정이 필요하면 packages/ui에서 수정
- 새 API 타입은 packages/shared에 추가
- 이 패키지 내에서는 로컬 컴포넌트만 생성해결책 2: 작업 범위 명시
Claude에게 요청할 때 범위를 명확히:
❌ "로그인 기능 추가해줘"
✅ "apps/web에 로그인 페이지 추가해줘.
@monorepo/api-client의 authApi를 사용하고,
UI는 @monorepo/ui의 Button, Input 컴포넌트 활용해줘."해결책 3: @파일 멘션 활용
"useAuth 훅 개선해줘.
참고: @src/hooks/useAuth.ts @src/lib/api/auth.ts"Claude가 관련 파일을 먼저 읽고 컨텍스트를 파악합니다.
4. 실전 Before/After
Before: Context 없이
요청: "상품 상세 페이지 만들어줘"
// pages/product/[id].js (Pages Router 사용 - 프로젝트는 App Router인데!)
import React from 'react';
import axios from 'axios'; // 프로젝트는 fetch 사용하는데!
export default function ProductPage({ product }) {
return (
<div style={{ padding: '20px' }}> {/* 인라인 스타일! */}
<h1>{product.name}</h1>
<p>${product.price}</p> {/* 가격 포맷 함수 있는데! */}
</div>
);
}
export async function getServerSideProps({ params }) { // SSG 아닌 SSR */
const res = await axios.get(`/api/products/${params.id}`);
return { props: { product: res.data } };
}문제점:
- 프로젝트 라우터 무시 (Pages vs App Router)
- 스타일링 컨벤션 무시 (인라인 → Tailwind)
- 기존 유틸 함수 무시 (formatPrice 등)
- HTTP 클라이언트 불일치 (axios vs fetch)
After: CLAUDE.md로 Context 제공
// app/products/[id]/page.tsx
import { getProduct } from '@/lib/api/products';
import { formatPrice } from '@/lib/utils/format';
import { ProductImage } from '@/components/features/ProductImage';
import { AddToCartButton } from '@/components/features/AddToCartButton';
interface Props {
params: { id: string };
}
export default async function ProductPage({ params }: Props) {
const product = await getProduct(params.id);
return (
<div className="container mx-auto px-4 py-8">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<ProductImage src={product.imageUrl} alt={product.name} />
<div className="space-y-4">
<h1 className="text-3xl font-bold">{product.name}</h1>
<p className="text-2xl text-primary">
{formatPrice(product.price)}
</p>
<p className="text-gray-600">{product.description}</p>
<AddToCartButton productId={product.id} />
</div>
</div>
</div>
);
}개선점:
- App Router 구조 준수
- 기존 컴포넌트 재사용
- 프로젝트 유틸 함수 활용
- Tailwind 스타일링
- TypeScript Props 인터페이스
5. CLAUDE.md 템플릿
바로 복사해서 쓸 수 있는 템플릿:
# [프로젝트 이름]
## 개요
[한 줄 프로젝트 설명]
## 기술 스택
- Language:
- Framework:
- Database:
- Infrastructure:
## 폴더 구조src/
├──
├──
└──
## 코딩 컨벤션
### 네이밍
- 컴포넌트:
- 함수:
- 상수:
### 스타일
- [스타일링 방식 명시]
### 에러 처리
- [에러 처리 패턴 명시]
## ⛔ 금지 사항
-
-
-
## 자주 쓰는 명령어개발 서버
빌드
테스트
린트
## 참고 문서
- [링크]마무리
Context는 단순한 설정이 아닙니다.
Claude가 당신의 팀원처럼 일하게 만드는 온보딩 문서입니다.
신입 개발자에게 설명하듯 CLAUDE.md를 작성하세요.
"이건 당연히 알겠지"라는 생각은 금물.
명시적일수록 결과가 좋아집니다.
다음 편에서는 Hooks를 활용해 Claude의 작업을 자동으로 검증하고,
팀 워크플로우에 통합하는 방법을 다룹니다.
시리즈 목차
- Context가 전부다 (현재 글)
- Hooks로 워크플로우 자동화
- Custom Skills로 팀 표준 만들기
- MCP 서버 구축하기
- 모델 믹스 전략