Cursorで効率的にコーディングする方法

codingbeginner4分で読める2026/6/4

Cursorで30日間コーディングしてみた——実際に効果のあった方法

100回は見たTypeScriptエラーの赤い波線を見つめながら、ネストされたジェネリクスでのOmitの正確な構文が思い出せない——そんな感覚をご存知ですか?3ヶ月前の私がまさにそうでした。Cursorを使い始めてから、複雑なプロジェクトではもう普通のVS Codeには戻れません。

でも、こういうことです:Cursorは魔法ではありません。最初の1週間は、高級オートコンプリートのように扱って、ゴミのような結果しか得られませんでした。30日間の意図的な練習の後、実際に時間を節約できるパターンと、時間を無駄にするパターンがわかりました。

重要なセットアップ

まず、基本を正しくしましょう。私はmacOSでCursor 0.45.xを実行していますが、同じ原則がWindows/Linuxにも適用されます。インストール後、ほとんどのチュートリアルがスキップする2つの設定をすぐに変更しました:

  1. インライン提案の「自動補完」を無効化(設定 > エディター > Cursor > 補完:オフ)。常に表示されるゴーストテキストが、キー入力ごとに迷いを生んでいました。代わりに、必要なときだけCtrl+Kでインライン生成をトリガーします。

  2. 「編集を適用」モードを有効化(Cmd+Shift+P > 「Cursor: 編集を適用の切り替え」)。これにより、Cursorが差分を表示するだけでなく、コードを直接変更できるようになります。大幅な時間短縮になります。

80/20の法則:実際に使う2つのコマンド

30日後、Cursorの使用は日常業務の80%をカバーする2つのコマンドに絞られました:

1. Cmd+K:「このブロックを修正」コマンド

これが基本中の基本です。コードブロックを選択し、Cmd+Kを押して、Cursorに何をすべきか指示します。以下は、私が構築しているReactプロジェクトの実際の例です:

// 私が書いたこの混乱を選択:
const handleSubmit = async (e) => {
  e.preventDefault()
  const data = new FormData(e.target)
  const body = {}
  for (let [key, val] of data.entries()) {
    body[key] = val
  }
  // ...さらに50行の手動バリデーション...
}

「react-hook-formとzodバリデーションを使用してリファクタリングし、ローディング状態を処理し、エラーバウンダリを追加」と入力しました。

Cursorが4秒で生成したもの:

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
})

type FormData = z.infer<typeof schema>

const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<FormData>({
  resolver: zodResolver(schema)
})

const onSubmit: SubmitHandler<FormData> = async (data) => {
  try {
    setError(null)
    await api.login(data)
    toast.success('ログインしました!')
  } catch (err) {
    setError(err instanceof Error ? err.message : 'ログインに失敗しました')
  }
}

コツ:使用したいライブラリとパターンを具体的に指定すること。「リファクタリング」だけでは汎用的なコードが生成されます。「react-hook-formとzodを使用してリファクタリング」と指定すると、実運用可能なコードが生成されます。

2. Cmd+L:「これを説明」コマンド

実はこれが最も強力な機能です。馴染みのないコードベースやレガシースパゲッティコードを扱うときに常に使用しています。

例:__getattr__を理解できない方法で使用しているPythonスクリプトをデバッグしていました:

class ConfigProxy:
    def __init__(self, config):
        self._config = config
    
    def __getattr__(self, name):
        if name.startswith('_'):
            return super().__getattr__(name)
        return self._config.get(name, None)

これをハイライトして、「このパターンを説明し、Pyright用に適切に型ヒントを付ける方法を示してください」と質問しました。

Cursorの応答は驚くほど詳細で、プロキシパターンを説明し、__getattr__が欠落した属性で無限再帰を引き起こすことを指摘し、Protocolを使用した型付きバージョンを提供しました:

from typing import Any, Protocol

class ConfigProtocol(Protocol):
    def get(self, key: str, default: Any = None) -> Any: ...

class TypedConfigProxy:
    def __init__(self, config: ConfigProtocol):
        self._config = config
    
    def __getattr__(self, name: str) -> Any:
        if name.startswith('_'):
            raise AttributeError(name)
        return self._config.get(name, None)

コツ:型付き言語を使用している場合は、常に「型ヒント」または「適切な型付け」を要求すること。Cursorは要求しない限り、型なしのコードをデフォルトで生成します。

ワークフローを変えたパターン

新しい機能に対して私が今行っていること:

  1. 関数を説明するコメントを書く(実装ではなく)
  2. コメントをハイライトしてCmd+Kを押す
  3. 生成されたコードを注意深くレビュー——必ず少なくとも1つのエッジケースを見逃している
  4. フォローアップのプロンプトで反復:「ネットワーク障害のエラー処理を追加」や「空の配列を処理するようにする」など

最近のプロジェクトの例:

// このコメントを書いた:
// ユーザーデータを取得し、5分間キャッシュし、
// stale-while-revalidateパターンを処理する関数

// Cursorが生成したもの(3回の反復後):
const userCache = new Map<string, { data: User; timestamp: number }>()
const CACHE_TTL = 5 * 60 * 1000

async function getUser(id: string): Promise<User> {
  const cached = userCache.get(id)
  const isStale = cached && Date.now() - cached.timestamp > CACHE_TTL
  
  if (cached && !isStale) {
    return cached.data
  }
  
  // Stale-while-revalidate:古いデータを即座に返し、バックグラウンドで更新
  if (cached && isStale) {
    fetchUser(id).then(data => {
      userCache.set(id, { data, timestamp: Date.now() })
    })
    return cached.data
  }
  
  const user = await fetchUser(id)
  userCache.set(id, { data: user, timestamp: Date.now() })
  return user
}

Cursorが失敗する箇所(そして代わりにすべきこと)

3つの大きな問題点に直面しました:

1. APIを幻覚することがある。 Cursorが、使用しているReactバージョンに存在しない依存配列を持つuseMemoフックを使用したコードを生成したことがあります。修正:常に生成されたコードを実際の依存関係のドキュメントと照合すること。

2. 大規模なリファクタリングが苦手。 5つのファイルにわたって「このReduxストアをZustandに変換」するよう依頼したところ、一貫性のないインポートと欠落したステートスライスの混乱が生じました。修正:リファクタリングは1ファイルずつ、ターゲットパターンについて明示的な指示とともに行うこと。

3. プロジェクト固有の規約に苦戦する。 私のチームはデータベースカラムにsnake_case、TypeScriptにcamelCaseを使用しています。Cursorは一貫してどこでもcamelCaseを生成します。修正:プロジェクトのルートに.cursorrulesファイルを作成し、規約を追加する:

# .cursorrules
- TypeScript変数にはcamelCaseを使用
- データベースカラム名にはsnake_caseを使用
- .then()よりもasync/awaitを優先
- エラー処理:常に型付きエラーでtry/catchを使用

本当の生産性向上の秘訣

最大の時間節約はコード生成ではなく、デバッグ支援です。不可解なエラーメッセージが表示されたとき、それをCursorのチャット(Cmd+L)に関連コードブロックとともにコピーします。これで以下のような場合に何時間も節約できました:

  • TypeScript型エラー:「型'X'は型'Y'に割り当て可能ではありません」→ Cursorが型の不一致を説明し、修正を提案
  • Reactレンダリング問題:「最大更新深度を超えました」→ CursorがuseEffectの依存関係の無限ループを特定
  • API統合バグ:「undefinedのプロパティを読み取れません」→ Cursorが非同期コードを追跡してnull参照を見つける

次のステップ

Cursorのすべての機能を一度に使おうとしないでください。以下が7日間の計画です:

1〜2日目:インラインコード生成にCmd+Kのみを使用。チャット、説明、コンポーザーは使わない。

3〜4日目:デバッグと馴染みのないコードの説明にCmd+Lを追加。まだコンポーザーは使わない。

5〜7日目:プロジェクトに.cursorrulesを追加し、複数ファイル編集にコンポーザーを試す。

7日後には、実際に効果のあるパターンの筋肉記憶が身についているでしょう。そして、避けられない幻覚や悪いリファクタリングに遭遇したとき、Cursorを信頼すべき時と自分でコードを書くべき時が正確にわかるようになります。

さあ、避けていたファイルを開き、最も醜い関数をハイライトして、Cmd+Kを押しましょう。未来の自分が感謝するはずです。

関連エージェント

C

Claude Code

Anthropic's AI-powered coding agent that helps you write, edit, and review code

続きを読む →