用途別 CLAUDE.md テンプレート は10種類の一般的なプロジェクトタイプをカバーしている。このガイドはさらに踏み込む: ここの各テンプレートには、各セクションがなぜ存在するか、どの具体的な Claude の挙動を防ぐか・可能にするかの注釈付きだ。最小限の例ではなく、実世界の複雑さに対応した本番対応の出発点だ。
テンプレート1: React SPA (Vite + TypeScript)
これがない場合に Claude が間違えがちなこと: Vite と CRA の前提を混ぜる、古い hook パターンを使う、既存のコンポーネントアーキテクチャを無視する、不要な依存関係を追加する。
# Project
顧客向けダッシュボード SPA。React 19、TypeScript strict モード、Vite 6。
状態管理: Zustand。データフェッチ: TanStack Query v5。
## Commands
```bash
pnpm dev # :5173 で Vite dev サーバー
pnpm build # TypeScript チェック + Vite ビルド
pnpm test # Vitest ユニットテスト
pnpm test:e2e # Playwright E2E テスト
pnpm lint # ESLint
pnpm typecheck # tsc --noEmit
Anti-Patterns
- prop drilling なし — クロスコンポーネント状態には Zustand を使う
- データフェッチに
useEffectなし — TanStack Query を使う - コンポーネントで直接 API 呼び出しなし — すべての API 呼び出しは
features/*/api.tsを通す any型なし —unknownを使い絞り込むか、適切な型を定義するshared/での barrel エクスポートなし — 直接インポートする- クラスコンポーネントなし
React.FC型なし — 通常の関数宣言を使う
State Management Rules
Zustand スライス: 機能ごとに1ファイル、名前付きフックとしてエクスポート。 サーバー状態に Zustand を使わない — それは TanStack Query の仕事。
Before Done
-
pnpm typecheckが通る(新しい TS エラーなし) -
pnpm lintが通る -
pnpm testが通る - 新しい prop drilling なし
- コンポーネントで直接 API 呼び出しなし
## テンプレート2: フルスタック Next.js アプリ
**これがない場合に Claude が間違えがちなこと:** App Router と Pages Router のパターンを混ぜる、誤ったサーバー/クライアントコンポーネント境界、サーバーデータにクライアントサイド状態を使う。
```markdown
# Project
B2B SaaS 製品。Next.js 15 App Router、TypeScript、Drizzle ORM 経由の PostgreSQL。
認証: Auth.js v5。スタイリング: Tailwind CSS 4。
## Commands
```bash
pnpm dev # Next.js dev サーバー
pnpm build # 本番ビルド
pnpm db:push # スキーマ変更をプッシュ(dev のみ)
pnpm db:migrate # マイグレーション生成と実行(本番)
React Server Components vs Client Components
デフォルトは Server Components。Client Component とする場合のみ:
- フック(
useState、useEffect、useContext)を使う - ブラウザ API を使う
- イベントリスナーを使う
// Server Component(デフォルト、ディレクティブ不要)
export default async function UserList() {
const users = await db.select().from(usersTable)
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
}
// Client Component(明示的な 'use client' 必須)
'use client'
export function SearchInput() {
const [query, setQuery] = useState('')
return <input value={query} onChange={e => setQuery(e.target.value)} />
}
Anti-Patterns
- 必要でない限りレイアウトレベルで
'use client'なし - クライアントコンポーネントでデータフェッチなし(楽観的更新を除く)
- 読み取りにサーバーアクションなし — ミューテーションのみ
- クライアントコンポーネントから直接 DB アクセスなし
pages/ディレクトリ — App Router のみ、Pages Router なし
## テンプレート3: Go REST API
**これがない場合に Claude が間違えがちなこと:** Go イディオムではなく命令的なエラー処理、ハンドラにビジネスロジックを混ぜる、`context.Context` 伝播の忘れ、誤ったテストテーブル構造。
```markdown
# Project
[サービス説明] の REST API。Go 1.23、Chi ルーター、pgx 経由の PostgreSQL。
## Commands
```bash
go run ./cmd/api # サーバー起動
go test ./... # 全テスト
go test ./... -race # レースディテクタ付き(PR 前に必ず実行)
golangci-lint run # lint
Error Handling
すべてのエラーは返す、panic しない(main での起動失敗を除く)。
エラーラッピング: fmt.Errorf("users: get by id: %w", err)。
// 良い例
func (s *Service) GetUser(ctx context.Context, id int64) (*User, error) {
user, err := s.repo.GetByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("users service: get user: %w", err)
}
return user, nil
}
Context Propagation
I/O を行うすべての関数の最初の引数として context.Context を渡す。構造体にコンテキストを格納しない。
Anti-Patterns
- グローバル状態なし — コンストラクターを通じた依存性注入を使う
init()関数なし — main での明示的な初期化- ハンドラで
panicなし — 常にエラーを返す - ハンドラで
log.Fatalなし — main のみ - エラーメッセージ: 小文字、末尾のピリオドなし
## テンプレート4: Nx モノレポ(TypeScript)
**これがない場合に Claude が間違えがちなこと:** 間違ったディレクトリからコマンドを実行する、apps/libs を間違った場所に作成する、プロジェクトグラフの暗黙の依存関係を見落とす。
```markdown
# Project
Nx モノレポ、React アプリと共有ライブラリ。TypeScript 全体。
アプリ: `web`(顧客ポータル)、`admin`(社内ダッシュボード)。
ライブラリ: `ui`(デザインシステム)、`data-access`(API クライアント)、`util`(共有ユーティリティ)。
## Commands
```bash
# 常に nx コマンドを使い、パッケージマネージャーの直接コマンドは使わない
nx run web:dev # web アプリの dev サーバー
nx run-many -t build # すべてビルド
nx affected -t test # 影響を受けたプロジェクトのみテスト
Boundaries(Nx が強制)
apps/ は以下からのみインポート可能: libs/
libs/ui は以下からインポート可能: (このリポジトリ内のものは何もない)
libs/data-access は以下からインポート可能: libs/util
これらのインポート境界に違反しない — Nx lint が検出するが、違反を導入しない。
Anti-Patterns
- アプリ境界をまたいだインポートなし(
webはadminからインポートできない) - アプリ間の共有状態なし(各アプリは独自の Zustand ストアを持つ)
- プロジェクト境界をまたぐ
../../インポートなし —@scope/lib-nameパスを使う
## テンプレート5: OSSライブラリ(TypeScript)
**これがない場合に Claude が間違えがちなこと:** バージョンバンプなしでパブリック API を壊す、ESM/CJS デュアルエクスポートを見落とす、内部ではなくパブリック API をテストする。
```markdown
# Project
`@yourscope/library-name` — [1行説明]。
npm に公開。Node.js 20+ とブラウザをサポート。
## Commands
```bash
pnpm build # tsup ビルド(ESM + CJS + 型)
pnpm test # Vitest
pnpm test:types # tsd — パブリック型シグネチャの検証
pnpm release # changeset バージョン + npm パブリッシュ(人間のみ)
Public API Rules
パブリック API = src/index.ts からエクスポートされるすべて。
破壊的変更はメジャーバージョンバンプが必要。破壊的 = 以下のいずれか:
- エクスポートの削除
- 関数シグネチャの変更(パラメータまたは戻り値の型)
- 型の必須プロパティの変更
- デフォルト動作の変更
追加はマイナー、修正はパッチ。changesets を使う: pnpm changeset。
Testing
パブリック API をテストする、内部ではない。src/index.ts 以外からインポートするテストがあれば、正しいものをテストしているか再考する。
Anti-Patterns
from module import *なし- バンドラー固有の機能なし(Vite/Webpack マジックなし)
- グローバルポリフィルなし — 必要なら peer dependency として要求する
## テンプレート6: React Native / Expo アプリ
**これがない場合に Claude が間違えがちなこと:** Web 専用 API の使用、プラットフォームの違いを無視、Expo 固有パターンの見落とし。
```markdown
# Project
Expo 53 アプリ(React Native 0.77)。TypeScript。iOS と Android。
ナビゲーション: Expo Router(ファイルベース)。
## Platform Differences
常に両プラットフォームで動作を確認する。一般的な違い:
- シャドウ: iOS `shadowOffset`/`shadowOpacity`、Android `elevation`
- テキストレンダリング: すべてのテキストを `<Text>` でラップ、裸の文字列なし
## Anti-Patterns
- Web 専用 API なし: `document`・`window`・`localStorage` は使わない — `expo-*` の等価物を使う
- 繰り返し要素のインラインスタイルなし — `StyleSheet.create()` を使う
- `FlatList` と `ScrollView` の混同なし: 長いリストには FlatList、短いコンテンツには ScrollView
- データに直接 `fetch` なし — TanStack Query のクエリ関数でラップする
テンプレート7: Chrome 拡張機能(Manifest V3)
これがない場合に Claude が間違えがちなこと: Manifest V2 API の使用、コンテンツスクリプトとサービスワーカーの混在、孤立ワールドモデルの誤解。
# Project
Chrome 拡張機能(Manifest V3)。TypeScript + React(ポップアップ/オプションページ)。
## Service Worker Rules
バックグラウンドサービスワーカーは DOM アクセスなし。`window`・`document`・`localStorage` は使えない。ストレージには `chrome.storage.local` または `chrome.storage.sync` を使う。
```typescript
// 良い例 — サービスワーカーで chrome.storage を使う
await chrome.storage.local.set({ key: value })
// 悪い例 — サービスワーカーで使用不可
localStorage.setItem('key', value) // undefined
Anti-Patterns
eval()なし — Manifest V3 CSP でブロックされる- リモートコード実行なし — すべてのスクリプトはバンドル必須
- サービスワーカーで
XMLHttpRequestなし —fetchを使う - サービスワーカーから DOM 操作なし
- 暗号化なしで
chrome.storageにセンシティブデータを格納しない
## テンプレート8: CLI ツール(TypeScript/Node.js)
**これがない場合に Claude が間違えがちなこと:** `process.exit()` の不適切な使用、stdin/stdout の誤った処理、クロスプラットフォームパス処理の見落とし。
```markdown
# Project
CLI ツール: `mycli` — [5単語で何をするか]。
Node.js 22+。TypeScript。esbuild でシングルバイナリ。
## CLI Design Principles
- 終了コード 0: 成功。終了コード 1: ユーザーエラー。終了コード 2: 内部エラー。
- すべてのエラーは `stderr` へ、出力は `stdout` へ
- マシン可読出力のための `--json` フラグをサポート
- `NO_COLOR` 環境変数をサポート
## Anti-Patterns
- 大きなファイルの同期読み取りなし — ストリームを使う
- ハードコードされた ANSI エスケープコードなし — chalk を使う
- ライブラリコードで `process.exit()` なし — CLI エントリーポイントのみ
- グローバルなミュータブル状態なし — 関数引数で設定を渡す
テンプレート9: インフラ / Terraform
これがない場合に Claude が間違えがちなこと: 誤ったリソースライフサイクル、変数バリデーションの欠如、安全でないデータソースパターン。
# Project
Terraform 1.9+ で管理される AWS インフラ。状態は S3、ロックは DynamoDB。
環境: dev・staging・prod。環境ごとに別の状態ファイル。
## Safety Rules
apply の前に plan — staging や prod で `terraform apply -auto-approve` は絶対にしない。
staging/prod で `prevent_destroy = false` のリソースには、なぜ保護されていないかコメントを追加する。
インデックスで参照する必要があるリソースに `count` を使わない — 安定したキーで `for_each` を使う。
## Anti-Patterns
- ハードコードされたリージョンなし — 変数を使う
- 明示的な人間の確認なしに `terraform destroy` しない
- サイレントに失敗しうるデータソースなし(フィルターなしの `data.aws_ami`)
- ハードコードされた認証情報なし — IAM ロールと assume role を使う
- すべてのリソースに `tags` 必須: `Environment`・`ManagedBy = "terraform"`・`Project`
テンプレート10: ドキュメントサイト(Astro/Docusaurus)
これがない場合に Claude が間違えがちなこと: コンテンツスキーマを壊す、存在しないコンポーネントを追加する、誤った frontmatter、誤った Markdown 方言。
# Project
Astro 5 で構築されたドキュメントサイト。コンテンツは `src/content/docs/`。
Cloudflare Pages にデプロイ。Pagefind で検索。
## Content Rules
すべての docs ページは `src/content/docs/` の Markdown ファイル。必須 frontmatter:
```markdown
---
title: "ページタイトル" # 必須
description: "SEO 説明" # 必須
sidebar:
order: 10 # サイドバーの位置(オプション)
---
上記以外の frontmatter フィールドを追加しない — ビルドエラーになる。
Anti-Patterns
- Markdown コンテンツに HTML なし(テーブルを除く — それは許容)
- 内部リンクに絶対 URL なし — 相対リンクを使う
- 1200px を超える画像なし
- コンポーネントシステムを理解せずに
src/components/を変更しない - コンテンツファイルに JavaScript なし — コンテンツは Markdown のみ
## テンプレートの選び方
これらのテンプレートは出発点であり、最終的な設定ではない。最も近いものから始め、スタックに当てはまらないセクションを削除し、実際のセットアップの具体的な情報を追加する。
一貫して最大の改善をもたらすテンプレートは、強いアンチパターンセクションと明示的な完了前チェックリストを持つものだ。既存の CLAUDE.md に2つだけ追加できるなら、その2つにする。
これらのパターンを効果的にするものの根拠については [CLAUDE.md ベストプラクティス 2026](/blog/claude-md-best-practices-2026) を参照。Python 固有のパターンは [Python 向け CLAUDE.md](/blog/claude-md-for-python-projects) で確認できる。