1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cursor Rulesを使いこなす:.cursor/rules でAIコーディングの質を劇的に上げた話

1
Last updated at Posted at 2026-03-27

AIの提案がいつも「惜しい」問題

Cursor を使い始めてしばらくすると、こんな不満が出てくる。

  • コード補完が any を使う(TypeScript strict モードなのに)
  • var で変数を宣言してくる
  • コンポーネントが250行を超えても分割してくれない
  • console.log を残したまま PR を作ろうとする
  • 自分のプロジェクト固有のユーティリティ関数を使わず、毎回ゼロから書き直す

これらは Cursor が悪いのではなく、AIにプロジェクト固有のルールが伝わっていないことが原因だ。

Cursor Rules を正しく設定すると、AIは「このプロジェクトのAIペアプログラマー」に変わる。本記事では、.cursor/rules/ ディレクトリを使ったProject Rules の実践的な設定方法を解説する。

Cursor Rulesの3種類を整理する

Cursor には現在3種類のルール設定がある。

種類 設定場所 スコープ バージョン管理
Project Rules .cursor/rules/*.mdc プロジェクト単位 できる(推奨)
User Rules Cursor設定画面 全プロジェクト共通 できない
.cursorrules プロジェクトルート プロジェクト単位 できる

.cursorrules はレガシーとして残っているが、現在は Project Rules(.cursor/rules/ が推奨される。理由はシンプルで、複数ファイルに分割して管理でき、ファイルごとに適用条件を細かく設定できるからだ。

Project Rulesのディレクトリ構成

実際に運用しているプロジェクトでは、こんな構成にしている:

.cursor/
└── rules/
    ├── 00-core.mdc              # 常時適用:基本方針・禁止事項
    ├── 10-typescript.mdc        # TypeScript ファイル編集時
    ├── 20-react-component.mdc   # Reactコンポーネント編集時
    ├── 30-testing.mdc           # テストファイル編集時
    └── 90-git-commit.mdc        # コミットメッセージ生成時

ファイル名の先頭に番号をつけることで、優先度の視認性が上がる。.mdc 拡張子はMarkdownにメタデータを付加したCursor独自の形式だ。

各ルールファイルの実践例

00-core.mdc(常時適用ルール)

---
alwaysApply: true
---

# Core Development Rules

## 禁止事項(絶対に守ること)
- `any` 型の使用禁止。不明な型は `unknown` を使い、型ガードで絞り込む
- `var` の使用禁止。`const` を優先し、必要な場合のみ `let` を使う
- `console.log` を本番コードに残さない
- マジックナンバーを直接使わない。名前付き定数として定義する

## プロジェクト固有のユーティリティ
- 日付フォーマットには `src/utils/date.ts``formatDate()` を使う
- API呼び出しには `src/lib/api.ts``apiClient` を使う(`fetch` を直接使わない)
- エラーハンドリングには `src/utils/error.ts``handleError()` を使う

## コメントルール
- 「何をしているか」ではなく「なぜそうしているか」をコメントに書く
- JSDoc はpublic関数のみ。internal関数への過剰なコメントは不要

alwaysApply: true にしたルールは、すべての会話で自動的にコンテキストに含まれる。プロジェクト全体に適用したい基本ルールをここに書く。

10-typescript.mdc(TypeScript向け)

---
alwaysApply: false
globs:
  - "**/*.ts"
  - "**/*.tsx"
---

# TypeScript Coding Rules

## 型定義
- オブジェクトの形状には `interface` を使う(`type` は Union/Intersection/Mapped types向け)
- 関数には必ず戻り値の型を明示する
- `as` キャストは最終手段。型ガードで絞り込む方法を先に検討する

## 関数スタイル
- `Promise` を直接扱わず、`async/await` を使う
- エラーは例外ではなく Result 型で表現する(`src/types/result.ts` 参照)

## 命名規則
- コンポーネント: PascalCase(例: `UserProfileCard`- 関数: camelCase + 動詞始まり(例: `fetchUserData`- 定数: SCREAMING_SNAKE_CASE(例: `MAX_RETRY_COUNT`- 型/インターフェース: PascalCase + 末尾に用途(例: `UserResponse`, `CreateUserInput`

globs でパターンを指定すると、該当ファイルを編集するときだけ自動的にルールが適用される。

20-react-component.mdc(React向け)

---
alwaysApply: false
globs:
  - "src/components/**/*.tsx"
  - "src/app/**/*.tsx"
---

# React Component Rules

## コンポーネント設計
- 1ファイルにつき1コンポーネント(150行を超えたら分割を検討)
- Propsインターフェースは `[コンポーネント名]Props` と命名
- デフォルトエクスポートは使わない(名前付きエクスポートを使う)

## Hooks
- カスタムフックは `src/hooks/` に配置し、`use` プレフィックスをつける
- `useEffect` の依存配列を省略しない。ESLint の `exhaustive-deps` ルールに従う
- グローバル状態は Zustand で管理(`useState` でローカル状態を管理しすぎない)

## 例
コンポーネントの基本構造:

\`\`\`typescript
interface UserCardProps {
  userId: string;
  onSelect?: (id: string) => void;
}

export function UserCard({ userId, onSelect }: UserCardProps) {
  // ...
}
\`\`\`

30-testing.mdc(テスト向け)

---
alwaysApply: false
globs:
  - "**/*.test.ts"
  - "**/*.test.tsx"
  - "**/*.spec.ts"
---

# Testing Rules

## テスト構造
- `describe` ブロックは「何をテストするか」、`it` ブロックは「どういう場合に何になるか」
- テストデータは `test/fixtures/` から読み込む(インラインに大量データを書かない)

## アサーション
- `expect(value).toBe(expected)` は primitive 値のみ
- オブジェクト比較は `toEqual` または `toMatchObject`
- 非同期テストには必ず `await` をつける

## 命名
\`\`\`typescript
// Good
it("should return null when user is not found", async () => {});
it("throws AuthError when token is expired", () => {});

// Bad
it("test user fetch", () => {});
it("works correctly", () => {});
\`\`\`

ルールの適用モードを使い分ける

.mdc ファイルのフロントマターで、適用タイミングを制御できる。

---
# 常時適用(すべての会話にコンテキストとして含まれる)
alwaysApply: true

# ファイルパターンに合致したとき自動適用
globs:
  - "src/components/**/*.tsx"

# AIが「関連する」と判断したときに適用(Cursorが自動判断)
description: "Use when working with database queries or Prisma schema"
---

description を設定したルールは、AIが会話の文脈から「このルールが関連する」と判断したときに自動で適用される。Prismaスキーマを編集しているときだけDBルールを適用したい、といったケースに便利だ。

チームでProject Rulesを使う際のポイント

バージョン管理に含める

# .gitignore には追加しない
git add .cursor/rules/
git commit -m "Add Cursor project rules for TypeScript/React"

Project Rules はコードと同じリポジトリで管理することで、チーム全員が同じAIアシスタントの挙動を得られる。新メンバーがクローンした瞬間から、プロジェクト固有のルールに従ったAI補完が使える。

ルールの粒度を適切に保つ

ルールが長すぎると、AIがコンテキストのどこに注目すべきか分からなくなる。目安として:

  • 1つのルールファイルは 200行以下
  • 1項目は 1〜3行で書く(長い説明よりも具体的な例を添える)
  • ネガティブルール(「〜してはいけない」)には必ず理由か代替案を添える

Cursor自身にルールをメンテナンスさせる

「このプロジェクトでよく使うパターンをルール化して」と Cursor に依頼すると、既存コードを読んで .cursor/rules/ に追記してくれる。ルール管理のコストを大幅に減らせる技だ。

設定前後の変化

実際にプロジェクトにProject Rulesを導入した結果:

Before:

  • AI提案に any が含まれることが多く、毎回手直しが必要
  • 自前のユーティリティを使ってくれず、fetch を直接書いてくる
  • テスト名が "test1" "works" のような意味のない名前になる

After:

  • unknown + 型ガードで型安全な提案が来る
  • apiClient を自然に使ったコードを提案してくれる
  • テスト名が "should return 404 when user does not exist" のように意味が通る

AIへの「お願い」をその場でタイプするのではなく、ルールファイルに一度書いておけば毎回伝わる。これがProject Rulesの本質的な価値だ。

まとめ:Cursor Rulesで「プロジェクト専用AI」を育てる

設定 効果
00-core.mdc(alwaysApply) 全会話に禁止事項と基本方針を伝える
10-typescript.mdc(globs) TSファイル編集時だけ型ルールを適用
20-react-component.mdc(globs) コンポーネント編集時にコンポーネント設計を守らせる
description 付きルール AIが文脈判断して自動適用

.cursor/rules/ はコードと同じようにバージョン管理でき、チームで共有できる。「毎回同じことをAIに説明している」と感じたら、それはルールにすべきサインだ。

Cursor Rulesは一度作れば育ち続ける資産になる。まずは 00-core.mdc に「このプロジェクトでやってはいけないこと」を3つ書くところから始めてみてほしい。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?