Cursorルールがない状態では、編集のたびにプロジェクトの規約に反するコードが生成されます。適切なルールを設定すると、プロジェクトに数ヶ月携わってきたシニア開発者が書いたようなコードが生成されます。この差は実際に計測できるものです。
本ガイドでは、Cursorが現在サポートする2つのルール形式を解説し、最も一般的なスタック向けのコピー&ペースト可能な7つのテンプレートを紹介します。最後に、よく書かれたルールでさえ機能しなくなる典型的な失敗パターンについても説明します。
2つの形式:.cursorrules vs .cursor/rules/*.mdc
Cursorは、ルートレベルの単一ファイル.cursorrulesから、.cursor/rules/配下のディレクトリベース形式へと移行を進めています。2026年時点では両方が機能しますが、動作と用途が異なります。
.cursorrules(レガシー、まだ機能する)
リポジトリのルートに置く単一のMarkdownファイルです。プロジェクト内のすべてのチャットと編集で自動的に読み込まれます。セットアップが簡単で網羅的にカバーできます。デメリットは、大規模プロジェクトでは一つのファイルが肥大化して扱いにくくなること。また、フロントエンドのルールとバックエンドのルールを特定ファイルタイプにスコープする方法がなく、同一ドキュメント内に混在します。
project-root/
└── .cursorrules
.cursor/rules/*.mdc(推奨)
各ルールの有効化タイミングと方法を制御するフロントマター付きのモジュール型ルールファイルです。各ファイルは.mdc拡張子を持ち、.cursor/rules/ディレクトリ配下に置きます。
project-root/
└── .cursor/
└── rules/
├── general.mdc
├── react-components.mdc
├── api-routes.mdc
└── testing.mdc
フロントマターは2つの主要フィールドをサポートします:
---
description: "このプロジェクトのReactコンポーネント規約"
globs: ["src/components/**/*.tsx", "src/app/**/*.tsx"]
---
description — 短いラベルです。“Agent Requested”モードでどのルールが関連するかを判断するためにCursorが使用します。
globs — ルールを自動でトリガーするファイルパターンです。globに一致するファイルを開くか編集すると、何もしなくてもルールが読み込まれます。
4つのルール種別
Cursorのルールシステムには4つの有効化モードがあります:
| 種別 | 有効化のタイミング |
|---|---|
| Always | すべてのチャットとComposerセッションで読み込まれる |
| Auto(globベース) | 一致するファイルを開いたときに読み込まれる |
| Agent Requested | descriptionに基づいてAIが読み込み判断 |
| Manual | 明示的に参照したときのみ読み込まれる |
ほとんどのプロジェクトでは、Always(グローバルな規約)とAuto(フレームワーク固有のルール)の組み合わせで十分です。
どちらの形式を使うか
5分で動かしたいなら.cursorrulesから始めてください。プロジェクトに複数の異なるレイヤー(フロントエンド/バックエンド/テスト)があり、それぞれに異なるルールが必要な場合や、単一ファイルが扱いにくくなった場合は.cursor/rules/に移行してください。以下のテンプレートは.cursorrules形式で書かれているため、どちらでも使えます——.cursorrulesファイルにそのまま貼り付けるか、フロントマターを除いて.mdcコンテンツとして使用してください。
テンプレート1:React / Next.js
最も一般的なWebスタックです。App Routerパターン、TypeScript規約、そしてCursorが最もつまずくコンポーネント構造の問題をカバーします。
# プロジェクトコンテキスト
App Router、TypeScript strictモード、Tailwind CSS、PostgreSQLのPrismaを使用したNext.js 15アプリケーション。
## テックスタック
- Next.js 15(App Router使用、Pages Routerではない)
- TypeScript strictモード。`any`禁止。`unknown` + 型ガードを使用すること。
- スタイリングにはTailwind CSS。条件付きクラスには`@/lib/utils`の`cn()`を使用すること。
- PostgreSQL使用のPrisma ORM
- 認証にはNextAuth.js v5
- パッケージマネージャーにはpnpm
## コンポーネントルール
- アロー関数コンポーネントを使用すること。クラスコンポーネント禁止。
- 名前付きエクスポートのみ。page.tsxとlayout.tsx以外はデフォルトエクスポート禁止。
- クライアントコンポーネントには先頭に"use client"を記述。デフォルトはServer Components。
- クライアントコンポーネントでデータフェッチしない。Server Componentsでフェッチし、propsとして渡すこと。
- Props インターフェース名:`ComponentNameProps`。コンポーネントの上で定義すること。
## ファイルとフォルダーの規約
- コンポーネント:`src/components/` — ケバブケースのファイル名、パスカルケースのコンポーネント名
- ページ:`src/app/` — App Routerの規約に完全に従うこと
- サーバーアクション:`src/actions/` — actionプレフィックス(例:`createUser.ts`)
- ユーティリティ:`src/lib/` — 純粋な関数、副作用なし
- 型:`src/types/` — 共有TypeScript型とインターフェース
## インポート順序
1. ReactとNext.js
2. サードパーティパッケージ
3. 内部エイリアス(`@/components`、`@/lib`など)
4. 相対インポート
5. CSS/スタイル
各グループの間に空行を入れること。`src/`からの相対パスではなく`@/`エイリアスを使用すること。
## コードスタイル
- セミコロンなし(Prettierが処理する)
- 文字列にはシングルクォート
- 2スペースインデント
- 最大行長:100文字
- 未使用のインポートや変数はエラーとして扱う
## データベース
- 生のSQLを書かない。Prisma Clientのみ使用すること。
- すべてのDB呼び出しは`src/lib/db/`の関数内に置くこと。ルートハンドラーやServer Actionsに直接書かない。
- ミューテーションはtry/catchで囲む。`{ data, error }`形式で返すこと。
## エラーハンドリング
- ページレベルのエラーにはNext.jsのerror.tsxを使用する
- APIルートは適切なHTTPステータスコードとともに`{ error: string }`を返す
- 内部のエラーメッセージをクライアントに公開しない
テンプレート2:Python(API / バックエンド)
FastAPIプロジェクト向けですが、多少の調整でFlaskやDjangoにも同様に適用できます。
# プロジェクトコンテキスト
FastAPIバックエンドサービス。Python 3.11+。PostgreSQL(asyncpg)とRedisを使用してRailwayにデプロイ。
## コードスタイル
- PEP 8を厳守
- すべての関数シグネチャに型ヒントを付ける——パラメーターと返り値の型
- パブリック関数にはdocstring:1行サマリー、非自明な場合はArgs/Returns/Raises
- 最大関数長:40行。それ以上ならヘルパーを抽出すること。
- ミュータブルなデフォルト引数禁止
## プロジェクト構造
- `app/routers/` — FastAPIルーターファイル、1ドメイン1ファイル(users、auth、items)
- `app/services/` — ビジネスロジック。DB呼び出しなし、サービスレベルのオーケストレーションのみ。
- `app/repositories/` — すべてのDBクエリ。生のDB行ではなくドメインモデルを返す。
- `app/models/` — Pydanticモデルとわけてファイルに入れたSQLAlchemyモデル
- `app/core/` — 設定、依存性、ミドルウェア
## FastAPI規約
- 依存性注入には`Depends()`を直接関数シグネチャに書くのではなく`Annotated`を使用
- ルーターのprefixとtagsはmain.pyではなくルーターファイルで定義
- すべてのエンドポイントにレスポンスモデルを付ける。生のdictを返さない。
- async/awaitを全体で使用すること。同期DB呼び出し禁止。
## データベース
- SQLAlchemy 2.0スタイルを使用(レガシーQuery APIではない)
- すべてのクエリはリポジトリレイヤーに置く。サービスレイヤーはリポジトリを呼び出す。
- マイグレーションにはAlembicを使用。Alembicのマイグレーション外でDBスキーマを変更しない。
- コネクションプール:asyncpg。すべてのDB関数で`asyncpg.TooManyConnectionsError`を処理すること。
## エラーハンドリング
- 明示的な`status_code`と`detail`を持つ`HTTPException`をraiseする
- ドメインエラーには`app/exceptions.py`にカスタム例外クラスを作成
- 未処理例外のグローバル例外ハンドラーを`main.py`に設定
## テスト
- 非同期テストにはpytest-asyncio付きのpytest
- 1テストファイル = 1ルーターファイル、`tests/routers/`に置く
- エンドポイントテストには`httpx.AsyncClient`を使用
- 外部サービスはモックする。テストで実際の外部APIを叩かない。
- `app/services/`と`app/repositories/`で最低80%のカバレッジ
テンプレート3:Go(CLIまたはサービス)
Goには強固な規約があり、Cursorはそれを理解していますが、実際に使用しているパターンを明示的に記述しておくと効果的です。
# プロジェクトコンテキスト
Go 1.22サービス。chiルーター、DBクエリにはsqlc、PostgreSQLはpgx/v5を使用したREST APIを公開。
## コードスタイル
- Effective GoとGoogle Go Style Guideに従う
- エラーハンドリング:エラーをその場で確認し、`fmt.Errorf("context: %w", err)`でラップする
- 本番コードパスにpanicなし。panicはinit()またはパッケージレベルのセットアップのみ
- 複雑な関数を明確にする場合を除き、名前付き返り値を避ける
- レシーバー名:型の1〜2文字の略称(例:`User`に対して`u`)
## プロジェクト構造
cmd/server/ — main.goのみ。依存性を注入してサーバーを起動する。 internal/ handler/ — HTTPハンドラー。サービスレイヤーを呼び出し、リクエスト/レスポンスを処理する。 service/ — ビジネスロジック。DBやHTTPの関心事を持たない。 repository/ — DBクエリ(sqlc生成 + 複雑なクエリの手書き) domain/ — ドメイン型とインターフェース pkg/ — 外部からインポートしても安全なユーティリティ
## エラーハンドリング
- センチネルエラーはそれが属するパッケージ内で定義する
- 比較には`errors.Is`と`errors.As`を使用——文字列マッチング禁止
- ハンドラーはサービスエラーをHTTPステータスコードに変換する——ハンドラーにビジネスロジックを置かない
## インターフェース
- インターフェースはプロバイダー側ではなく、使用する側(コンシューマーパッケージ)で定義する
- インターフェースは小さく保つ。1〜2メソッドが理想。
- インターフェースを受け取り、構造体を返す
## データベース
- すべてのクエリはsqlc生成コード経由。sqlcで表現できないクエリのみ手書きする。
- pgx/v5を直接使用。ORMなし。
- トランザクション:トランザクションが必要なリポジトリメソッドは第1引数に`pgx.Tx`を受け取る
## テスト
- 純粋な関数にはテーブル駆動テスト
- テストアサーションには`testify/require`を使用
- 統合テストは`_test.go`ファイルに`//go:build integration`ビルドタグを付けて配置
- インターフェースのモックには`mockery`生成モックを使用
テンプレート4:TypeScript(Node.jsバックエンド)
TypeScriptを使ったNode.jsバックエンドは、フロントエンドのTypeScriptとは異なるパターンが必要です。このテンプレートはExpressまたはHonoベースのAPIに対応しています。
# プロジェクトコンテキスト
TypeScript、Hono、バリデーションにZod、Drizzle ORM、PostgreSQLのNode.js REST API。Bun上で動作。
## TypeScript設定
- tsconfig.jsonで`strict: true`
- `any`禁止。本当に不明なデータには`unknown`を使い、明示的にナローイングすること。
- `noUncheckedIndexedAccess: true` — 配列アクセス結果を必ず確認すること
- このプロジェクトでは`interface`より`type`を優先(チームの方針)
## プロジェクト構造
src/ routes/ — Honoルートファイル、1ドメイン1ファイル services/ — ビジネスロジック db/ schema.ts — Drizzleスキーマ定義 queries/ — クエリ関数、1テーブル1ファイル middleware/ — 認証、ロギング、エラーハンドラー lib/ — 共有ユーティリティ types/ — 共有TypeScript型
## バリデーション
- すべてのリクエストボディとパラメーターをZodスキーマでバリデーション
- スキーマはルートファイルと同じ場所に置く`schema.ts`ファイルで定義する
- Zodのparseを通過していない入力を決して信用しない
## エラーハンドリング
- `statusCode`と`code`フィールドを持つ`Error`を継承したカスタム`AppError`クラスを作成
- 中央のエラーハンドラーミドルウェアがすべての`AppError`インスタンスをキャッチ
- すべてのエラーに`{ error: { code: string, message: string } }`形式で返す
- サービスレイヤーでは`Result<T, E>`パターンを使用。例外的な状況のみthrowする。
## データベース
- すべてのクエリは`src/db/queries/`に配置——サービスやルートに生SQLを書かない
- すべてのパラメーター化クエリにはプリペアドステートメントを使用
- 生のDB行をそのまま返さない。クエリレイヤーでドメイン型にマッピングすること。
## 非同期
- `async/await`を全体で使用。コールバックスタイル禁止。
- Promiseのリジェクションを明示的に処理する。浮いているPromise禁止。
- 独立した並列操作には`Promise.all()`を使用
テンプレート5:Pythonデータサイエンス / ML
データサイエンスプロジェクトは本番Pythonとは異なる規約が必要です。このテンプレートはノートブック、スクリプト、MLパイプラインに対応しています。
# プロジェクトコンテキスト
Python 3.11の機械学習プロジェクト。PyTorch、pandas、scikit-learn、実験追跡にMLflowを使用。Jupyterノートブックで開発し、本番コードはsrc/に置く。
## コードスタイル
- src/の関数には型ヒントを付ける。ノートブックは緩い。
- Blackフォーマット、88文字の行長
- インポート順序にisort
- 暗黙より明示を優先。明確さのために長い変数名を使う、賢さを見せようとしない。
## プロジェクト構造
data/ raw/ — 元のデータ、絶対に変更しない processed/ — クリーニング・変換済みデータ features/ — 特徴量エンジニアリング済みデータセット notebooks/ — 探索とプロトタイピング src/ data/ — データ読み込みと前処理モジュール features/ — 特徴量エンジニアリングパイプライン models/ — モデル定義とトレーニングスクリプト evaluation/ — メトリクスと評価ユーティリティ mlruns/ — MLflow実験追跡(自動生成)
## データ処理
- 生データは読み取り専用。data/raw/配下のファイルを変更しない
- すべてのデータ変換は新しいDataFrameを返す——メモリが文書化された制約でない限り、インプレース変更禁止
- 形状の前提を文書化する:`# (N, 4)を想定 — [timestamp, open, high, close]`
- パブリック関数ではエントリー時にDataFrameの形状とdtypesをバリデーションすること
## 再現性
- すべてのトレーニングスクリプトの先頭でランダムシードを設定:`torch.manual_seed(42)`、`np.random.seed(42)`
- 最終的なメトリクスだけでなく、すべてのハイパーパラメーターをMLflowに記録する
- requirements.txtで正確なパッケージバージョンを固定する(`>=`は使わない)
## モデルコード
- モデル定義とトレーニングループを分離する
- トレーニングループはMLflowに記録:パラメーター、エポックごとのメトリクス、最終アーティファクト
- モデルチェックポイントはMLflowのアーティファクトに保存——任意のローカルパスに保存しない
- 評価関数はメトリクス名と値のプレーンdictを返す——副作用なし
## テスト
- src/ユーティリティと前処理関数にはpytest
- 最低でも、小さな合成データセットでパイプラインがエラーなく動作することをテストする
- テストにネットワーク呼び出しなし。外部データソースはモックすること。
テンプレート6:React Native / Expo
Cursorが明示的なルールなしで間違えやすいモバイル固有のパターンです。
# プロジェクトコンテキスト
Expo SDK 52、TypeScript、ナビゲーションにExpo Routerを使用したReact Nativeアプリ。対象プラットフォーム:iOSとAndroid。
## コンポーネントルール
- React Nativeのプリミティブを使用(View、Text、Pressable)——div/button/pは使わない
- すべてのスタイルにStyleSheet.create()を使用。インラインスタイルオブジェクト禁止。
- `style={{ marginTop: 10 }}`はNG——StyleSheetでスタイルを定義すること。
- 小さいタップターゲットにはPressableHitSlopを最低でも`{ top: 10, bottom: 10, left: 10, right: 10 }`に設定
## ナビゲーション(Expo Router)
- app/ディレクトリ内のファイルベースルーティング——Expo Routerの規約に完全に従うこと
- 型付きルート:型付きルートパラメーターで`expo-router`の`href`を使用する
- Stack、Tabs、ModalレイアウトはそれぞれのLayout.tsxで定義する
- `router.push()`/`router.replace()`でナビゲート——`navigation.navigate()`は使わない
## プラットフォーム固有のコード
- プラットフォームの差異にはPlatform.select()またはPlatform.OSチェックを使用
- 差異が大きい場合はプラットフォーム固有ファイル:`Component.ios.tsx`/`Component.android.tsx`
- 両プラットフォームで必ずキーボード回避動作をテストすること——`behavior={Platform.OS === 'ios' ? 'padding' : 'height'}`で`KeyboardAvoidingView`を使用
## 状態管理
- グローバル状態にはZustand。派生/アトミック状態にはJotai。
- サーバー状態にはReact Query。コンポーネントにカスタムフェッチロジックを書かない。
- 永続化にはAsyncStorage——ストアアクション経由でのみアクセス、コンポーネントから直接触らない
## パフォーマンス
- 高コストな計算とリストアイテムに渡すコールバックには`useMemo`と`useCallback`を使用
- 20件以上のリストにはFlatListではなくFlashListを使用
- レンダー内でのインライン関数を避ける——特にリストアイテムへのpropsとして渡す場合
- リストアイテムのコンポーネントに`React.memo()`を適用
## テスト
- Jest + React Native Testing Library
- `fireEvent.click()`ではなく`fireEvent.press()`を使用
- ナビゲーションを含むテストでは`expo-router`をモックすること
テンプレート7:モノレポ(Turborepo / pnpm Workspaces)
モノレポでは、パッケージ間の境界を明確にし、相互汚染を防ぐルールが必要です。
# プロジェクトコンテキスト
pnpmワークスペースを使用したTurborepoモノレポ。Next.jsウェブアプリ、React Nativeモバイルアプリ、共有UIコンポーネントライブラリ、共有ユーティリティパッケージを含む。
## パッケージ構造
apps/ web/ — Next.js 15アプリ(アプリ固有のルールはapps/web/CURSOR.mdを参照) mobile/ — Expo React Nativeアプリ packages/ ui/ — 共有Reactコンポーネントライブラリ(WebとMobile両方で動作) utils/ — 共有TypeScriptユーティリティ(React不使用、プラットフォーム固有のコードなし) config/ — 共有ESLint、TypeScript、Tailwind設定
## パッケージの境界
- `packages/utils`はReact依存関係ゼロ——純粋なTypeScriptのみ
- `packages/ui`のコンポーネントはWebとMobile両方のコンテキストで動作すること
- アプリはpackagesからインポートできる。PackagesはAPPSからインポートしてはならない。
- パッケージ間の循環依存禁止。
## 共有UIコンポーネント
- packages/uiのコンポーネントは単一のindex.tsからエクスポートする
- プラットフォームの動作が異なる場合、各コンポーネントにWebバリアントとMobileバリアントを持たせる
- エクスポート:`ComponentName`(プラットフォーム非依存)、`ComponentNameWeb`、`ComponentNameNative`
- コード共有を最大化するために`react-native-web`プリミティブを使用
## Turborepoパイプライン
- 影響を受けるすべてのpackage.jsonファイルを更新せずにturbo.jsonに新しいスクリプトを追加しない
- `build`は上流の`build`に依存する。`dev`は依存しない。
- キャッシュキー:turbo.jsonのenv設定に関連する環境変数を含める
## TypeScript
- 各パッケージは`@repo/config/tsconfig/base.json`を継承した独自のtsconfig.jsonを持つ
- `paths`エイリアスはパッケージごとに設定されている——Webのエイリアスが他のパッケージでも使えると思わないこと
- プッシュ前にルートから`tsc --build`を実行してすべてのパッケージをまとめてチェックする
ベストプラクティス
各ルールファイルを200行以内に保つ
Cursorにはコンテキスト制限があります。400行の.cursorrulesファイルは切り詰められたり希釈されたりします。.cursor/rules/形式を使ってフォーカスしたモジュールに分割してください。全般的な規約は1ファイルに、フレームワーク固有のルールは別ファイルに、テストルールはさらに別ファイルに。
説明的ではなく、規定的に書く
弱いルール:「TypeScriptを適切に使用してください。」
強いルール:「any禁止。unknownを使い、型ガードでナローイングすること。noUncheckedIndexedAccessが有効です——配列アクセスの結果を必ず確認すること。」
最初の例はCursorがすでに知っていることを伝えるだけです。2番目の例は、あなたのプロジェクトが具体的に何を要求するかを伝えます。
非自明な決定にはその理由を文書化する
プロジェクトに自明でない規約がある場合は、なぜそれが存在するかを書いてください。Cursorはより確実にそれに従い、「改善」と思って勝手にオーバーライドすることが減ります。
# データベースレイヤーはthrowではなく{ data, error }タプルを返す。
# 理由:非同期と同期のコードパスで一貫したエラーハンドリングができ、
# サービスレイヤーでのtry/catchのネストを避けられる。
コンテキストに応じた有効化にglobsを使う
.cursor/rules/では、globsを使って関連する場合のみルールを読み込みます。テストルールがコンポーネント生成を汚染しないようにしてください。データベースルールがフロントエンドのコンテキストに現れないようにしてください。
---
description: "Vitestテスト規約"
globs: ["**/*.test.ts", "**/*.spec.ts", "src/test/**"]
---
大きなコンテキストには外部ファイルを参照する
ルールファイルは段階的開示のために@file参照をサポートしています。複雑なデータモデルがある場合は、それを埋め込む代わりにリンクしてください:
完全なデータベーススキーマは @schema.prisma を参照してください。
すべてのAPIレスポンス型は @src/types/api.ts を参照してください。
これによりルールファイルを集中させながら、必要なときに詳細にアクセスできます。
よくある失敗パターン
曖昧すぎるルール
「クリーンで保守しやすいコードを書いてください」は意味がありません。Cursorはすでにそれを目指しています。ルールはあなたの具体的な決定——Cursorがコードベースだけから推測できない決定——をエンコードする必要があります。
矛盾するルール
ルールが「デフォルトエクスポート禁止」と言っているのに、既存のファイルがすべてデフォルトエクスポートを使っていれば、Cursorはルールを無視して既存のコードパターンに従います。まずコードベースを修正するか、「新しいファイルのみ適用——レガシーファイルはデフォルトエクスポートを使っているが、新しいものは追加しない」のような注記を加えてください。
スタックのバージョン情報の欠如
「Next.js App Routerのパターンを使用してください」はバージョン番号なしでは意味がありません。Next.js 13と15のApp Routerでは、パターンが意味のある形で異なります。バージョンを含めてください。
大規模プロジェクトで1つの巨大ファイルを使う
12の異なるサブシステムのルールが入った単一の.cursorrulesでは、各サブシステムへの実効的な影響が弱まります。.cursor/rules/形式を使ってドメインごとに分割してください。
実際のファイル構造を無視したルール
プロジェクトにサービスレイヤーのフォルダーがない場合、「サービスレイヤーにサービスロジックを置いてください」というルールに従うことはできません。ルールはプロジェクトに既に構造的に存在するものを記述しているときに最もよく機能します。
はじめ方
ゼロから始める場合は、自分のスタックに最も近いテンプレートを選び、3つのことを実行してください:
- テックスタックのセクションを実際のバージョンに書き換える
- プロジェクトに適用されないセクションを削除する
- Cursorがコンテキストだけでは知れないプロジェクト固有の規約を2〜3個追加する
数セッション使ってみて、Cursorがまだ間違えている箇所をメモしてください。それがルールで埋めるべきギャップです。ルールは生きたドキュメントです——1日目に書いたバージョンは、30日目に役立つバージョンとは異なるものになります。
.cursor/rules/への移行については、.cursorrules から新しい形式への移行ガイドを参照してください。CursorルールとCLAUDE.mdのどちらを使うか検討中の場合は、2つの形式の比較もご覧ください。また、ルールギャラリーでは実際のプロジェクトで使われているAIコーディングルールのコレクションを閲覧できます。