Claude Codeを使ったAI駆動アプリ開発入門

【実践】メモアプリを作ってみよう

Claude Codeは、CLI上で動くLLMによるAI開発支援ツールです。本連載は全5回を予定しています。実務経験1~3年程度のエンジニア向けに、対話モードでの会話の基本、コンテキストと@記法、スラッシュコマンドとパーミッションの基本を解説し、最後に学んだ知識を総動員してアプリ開発をハンズオンで体験します。なお本連載は2026年9月刊行の『Claude Codeで作って学ぶ AI駆動アプリ開発入門』から一部を抜粋・編集してお届けします。

本書の第2章では1つのプロンプトでWebサイトを作りました。ここからは、これまでの連載で学んだ知識を組み合わせて、本格的なWebアプリ開発に挑戦します。

今回のシナリオ

ある日、上司からこんな依頼が来ました。「⁠簡単なメモアプリを今日中に作ってほしい⁠」⁠。機能は以下のとおりです。

  • 自分用メモの追加・編集・削除
  • カテゴリ分類(仕事・個人・アイデア)
  • ブラウザを閉じてもメモが消えない永続化
  • データベース不使用

ここまで学んできた知識を活かせば十分に対応できます。対話テクニック(連載第1回⁠)⁠、コンテキストの知識(第2回⁠)⁠、@記法(第2回⁠)⁠、スラッシュコマンド(第3回⁠)⁠、パーミッション設定(第4回)を組み合わせて、実際にアプリを作ってみましょう。

大切なのは、いきなり全機能を一度に指示しないことです。各ステップで動作を確認しながら進めることで、意図のズレを早い段階で発見できます。5つのステップに分けて、1つずつ確認しながら進めていきます。

完成イメージ

最終的に、以下の機能を持つメモアプリを作ります。

メモアプリの機能一覧
機能 内容
メモの追加 テキストを入力して追加ボタンでメモを保存
メモの編集 既存のメモの内容を修正
メモの削除 不要なメモを削除
カテゴリ分類 仕事・個人・アイデアの3種類で分類
永続化 ブラウザを閉じてもデータが残る

これらの機能を5つのステップで段階的に構築していきます。

始める前の準備⁠:承認モードを確認しよう

開発を始める前に、画面下部のステータスラインを確認しておきましょう。accept edits onやplan mode onなどのモード表示がなければ、Manualモードです。もし別のモードになっている場合は、Shift+Tabを押してモードを切り替えましょう。

Manualモードでは、Claude Codeがファイルを作成・編集するたびに確認画面が表示されます。初めてのアプリ開発では、1つひとつの変更を確認しながら進めることで、意図しない変更を把握しやすくなります。まずはManualモードで確認しながら進め、Step 1のファイル編集のタイミングでAuto-Acceptモードへ切り替えます。パーミッション設定(settings.json)はStep 1の後で設定します。

Step 1⁠:プロジェクトを作成しよう

最初のステップでは、Reactプロジェクトの環境を構築します。ここを終えると、すぐにブラウザで動く画面を確認できるようになります。

ターミナルで、メモアプリを作成するディレクトリに移動し、Claude Codeを起動しましょう。今回はデスクトップに作成した「workspace」フォルダの中にメモアプリのプロジェクトを作成していきます。エクスプローラー(Windows)やFinder(macOS)でデスクトップに「workspace」フォルダを作成し、移動してからClaude Codeを起動します。

cd ~/Desktop/workspace
claude

第1回で学んだ複数行入力(\ + Enter)を使って、環境構築の指示を出してみましょう。プロンプト入力中に自身が読みやすいように改行したり、条件が複数あるときは箇条書きで整理して伝えると意図が正確に伝わります。

> Reactでメモアプリを作りたいです。\
 以下の条件でプロジェクトを作成してください。\
 - プロジェクト名: memo-app\
 - Viteで作成(テンプレートはReact)\
 - 不要な初期ファイルや記述は編集・削除

指示した内容に応じて、Claude Codeがプロジェクトの作成を開始します。Reactプロジェクトを新規作成するシェルコマンドである npm create ... を実行しようとしています。確認画面が表示されますので、内容を確認して「Yes」を選択しましょう。

Bash command

  npm create vite@latest memo-app -- --template react 2>&1
  Create Vite React project named memo-app

This command requires approval

Do you want to proceed?
› 1. Yes
  2. Yes, and don't ask again for: npm create:*
  3. No

Reactプロジェクトが作成されたら、npm install(パッケージのインストール)や不要ファイルの削除など、自動的に次のアクションに進んでくれます。それぞれ同様の確認画面が表示されるので、内容を確認して「Yes」を選択しましょう。以降、本書ではシェルコマンドの確認にはYesを選択して進めることを前提として説明します。

「不要な初期ファイルや記述は編集・削除」と指定しているため、ファイルの上書き(overwrite)について確認が入るはずです。このとき、2番目の選択肢を選んで、Auto-Acceptモードに切り替えましょう。

Do you want to overwrite index.css?
  1. Yes
› 2. Yes, allow all edits during this session (shift+tab)
  3. No

2番目を選択すると、ステータスラインに「accept edits on」と表示され、Auto-Acceptモードに切り替わります。以降のステップでは、ファイルの編集は承認なしで自動的に進みます。以降、本書のハンズオンではAuto-Acceptモードを前提として説明します。慣れないうちは、自動で進む範囲がファイル編集だけに限られるAuto-Acceptモードで動作を把握しながら進め、慣れてきたら操作の安全性判定をauto modeに任せる、という使い分けがおすすめです。

Auto-Acceptモードが自動承認するのはファイルの作成・編集のみです。npm install や mkdirなどのシェルコマンドには引き続き確認が表示されます。シェルコマンドの確認についてはStep 1の後でパーミッション設定を行います。

プロジェクトの作成が完了すると、Claude Codeが完了報告をしてくれます。以下は、Claude Codeからの報告の一例です。最初に指示した通り、不要なファイルを削除し、初期ファイルを整理してくれます。

⏺ ビルドも通りました。プロジェクトの準備ができています。

 完了した内容
 
 削除したファイル:
 - src/App.css ̶ Viteデモ用のスタイル
 - src/assets/react.svg ̶ Reactロゴ
 - public/vite.svg ̶ Viteロゴ

 クリーンアップしたファイル:
 - src/App.jsx ̶ カウンターデモを除去し、シンプルなスケルトンに
 - src/index.css ̶ デモ用スタイルを除去し、最小限のリセットCSSに

 最終的なファイル構成:
 memo-app/
 ├- src/
 │ ├- App.jsx # メインコンポーネント(空のスケルトン)
 │ ├- index.css # 最小限のリセットCSS
 │ └- main.jsx # エントリーポイント
 └- ...

 開発サーバーを起動するには:
 cd memo-app
 npm run dev

動作確認⁠:開発サーバーの起動

Claude Codeが作業を終えたら、ブラウザで動作を確認しましょう。開発サーバーの起動は、Claude Codeとは別のターミナルで自分で実行します[1]。

新しいターミナルタブを開き、memo-appに移動して開発サーバーを起動してください。

cd ~/Desktop/workspace/memo-app
npm run dev

起動すると、次のような出力が表示されます。Reactの開発サーバーは、デフォルトで http://localhost:5173 というURLでアクセスできます。

> memo-app@0.0.0 dev
> vite

  VITE v7.3.1  ready in 328 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

ブラウザで http://localhost:5173 にアクセスし、Reactの初期画面が表示されれば成功です。

Reactの開発サーバー起動後の初期画面
Reactの開発サーバー起動後の初期画面(「Memo App」と表示された初期状態のブラウザ画面)

このターミナルは開発中はそのまま開いたままにしておきます。コードを変更すると、開発サーバーが自動的にリロードされて変更が反映されます。もし誤って閉じてしまったときは、同じ手順で再起動してください。

/init でCLAUDE.mdを生成する

環境の準備が完了したところで、CLAUDE.mdも生成しておきましょう。CLAUDE.mdはプロジェクトの情報をClaude Codeに伝えるためのファイルで、詳しくは本書の第4章で解説しています。CLAUDE.mdはmemo-appの中に作るので、ここで一度Claude Codeを終了し、「⁠~/Desktop/workspace/memo-app」に移動してから起動し直しましょう。

> /exit
cd ~/Desktop/workspace/memo-app
claude

移動できたら、第3回で学んだ /init を実行して、CLAUDE.mdの雛形を生成します。

> /init

このコマンドを実行すると、Claude CodeがCLAUDE.mdの雛形を生成してくれます。以下はCLAUDE.md を生成した際の出力の一例です。初期状態のReactプロジェクトで使われている技術情報を反映してくれています。

⏺ CLAUDE.md を作成しました。内容:
  - Commands ̶ dev / build / preview / lint の4コマンド
  - Architecture ̶ 現時点のシンプルな構成(ルーター・状態管理なし)と各ファイルの役割
  - Tech Stack ̶ React 19 / Vite 7 / ESLint 9 の構成
  - ESLint Notes ̶ flat config 形式と no-unused-vars のパターン例外

これでStep 1の環境構築は完了です。プロジェクトが作成され、開発サーバーが動き、CLAUDE.mdも用意できました。

パーミッション設定を追加する

Step 1の作業中、npm installやmkdirなどのシェルコマンドのたびに確認が表示されていました。Auto-Acceptモードに切り替えたのでファイルの作成・編集は自動で承認されるようになりましたが、シェルコマンドの確認はAuto-Acceptモードの対象外です。

第4回で学んだパーミッション設定を使えば、シェルコマンドの承認も効率化できます。このハンズオン向けの.claude/settings.jsonを作成しましょう。プロジェクトの中に.claude/ディレクトリを作り、その中にsettings.jsonファイルを作成してください。テキストエディタ(VS Codeやメモ帳など)で以下の内容を記述します。

.claude/settings.json に記述するパーミッション設定
{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run *)",
      "Bash(mkdir *)",
      "Bash(touch *)",
      "Bash(cp *)"
    ],
    "deny": [
      "Bash(sudo *)",
      "Bash(rm -rf *)"
    ],
    "ask": [
      "Bash(rm *)"
    ]
  }
}

第4回で紹介したdeny・ask・allowの考え方に基づいた設定です。allowにはこのハンズオンで頻繁に使うコマンドを登録し、denyとaskで危険な操作を制御しています。settings.jsonの変更は保存した時点で即座に反映されます。

Step 2⁠:メモの追加⁠・表示機能を作ろう

まずはメモを入力して一覧に表示する、最も基本的な機能から始めます。以下のようなプロンプトを送信します。

> メモアプリの最初の機能を作ってください。\
 - テキスト入力欄と「追加」ボタンを配置\
 - ボタンを押すとメモが一覧に追加される\
 - メモには作成日時も表示する

プロンプトに沿ってClaude Codeがコードを実装してくれます。Reactの経験は必要ありません。Reactでは、画面を「コンポーネント」と呼ばれるUIの部品に分けて作ります。入力フォームやメモ一覧といったパーツがそれぞれ独立したコンポーネントになるため、後から修正や機能追加がしやすくなります。ここでは「どんなコードが書かれたか」よりも「指示したとおりに動くか」を確認することに集中しましょう。以下は、メモの追加・表示機能を追加した際の出力の一例です。

⏺ 実装完了です。以下の機能を追加しました。

 機能
 - テキストエリアにメモを入力 → 「追加」ボタンまたは Enter でリストに追加
 - 各メモに作成日時(yyyy/mm/dd hh:mm:ss 形式)を表示
 - 入力が空のとき「追加」ボタンを無効化
 - メモがない場合は「メモがありません」を表示

 実装の要点
 - App.jsx:6 ̶ Intl.DateTimeFormat で日本語ロケールのフォーマット
 - App.jsx:14 ̶ memos 配列のイミュータブル更新(スプレッド構文)
 - App.jsx:25 ̶ crypto.randomUUID() でキー生成
 - Shift+Enter は改行として使えるよう Enter のみ追加に割り当て
 npm run dev で動作確認できます。

動作確認⁠:メモの追加と表示

コードが書き上がったら、ブラウザで動作を確認します。先ほど別ターミナルで起動した開発サーバーが動いていれば、ブラウザが自動的にリロードされているはずです。開発サーバーを閉じてしまっていた場合は、「⁠cd ~/Desktop/workspace/memo-app && npm run dev」で再起動してから確認してください。以下を確認しましょう。

  • テキスト入力欄が表示されている
  • 追加ボタンがある
  • テキストを入力して追加を押すと、メモが一覧に表示される
  • メモに作成日時が表示されている
メモ追加機能を実装した初期状態の画面
メモ追加機能を実装した初期状態の画面(「メモアプリ」の見出し、入力欄、追加ボタン、「メモがありません」の表示)

実際にテキストを入力して追加を押すと、メモが一覧に表示されることを確認してください。

メモを1件追加した後の一覧表示
メモを1件追加した後の一覧表示(「テスト」というメモと作成日時が表示されている)

Step 3⁠:メモの編集⁠・削除機能を追加しよう

メモの追加と表示ができるようになりました。ただ、このままでは入力ミスに気づいても修正できず、不要なメモも消せません。次は既存メモの編集と削除機能を追加して、メモを管理できるようにしましょう。

このステップでは、第2回で学んだ@記法を使ってみましょう。Reactにおいてメインのコンポーネントである src/App.jsx というファイルを明示的に指定しつつ、編集・削除機能を追加します[2]。

> @src/App.jsx を参照して、以下の機能を追加してください。\
 - 各メモに「編集」ボタンと「削除」ボタンを追加\
 - 「編集」ボタンを押すとメモの内容を修正できる\
 - 「削除」ボタンを押すとメモが一覧から消える

@src/App.jsxと指定することで、Claude Codeはこのファイルの内容をコンテキストに読み込んだ状態で作業を始めます。第2回で学んだとおり、@記法を使うとプロンプト送信時点でファイルの内容がコンテキストに含まれるため、より正確な修正が期待できます。

動作確認⁠:編集⁠・削除の操作

メモ機能を追加した時と同様にブラウザで操作して、意図どおりに動くことを確かめましょう。開発サーバーが停止していた場合はnpm run devで再起動してください。

  • 各メモに編集・削除ボタンが表示されている
  • 編集ボタンを押すと、メモの内容を修正できる
  • 修正後に保存を押すと、内容が更新される
  • 削除ボタンを押すと、メモが一覧から消える
編集・削除ボタンが追加されたメモ一覧
編集・削除ボタンが追加されたメモ一覧(「テスト」というメモに編集・削除ボタンが並んでいる)
メモのタイトルを編集している操作画面
メモのタイトルを編集している操作画面(「テスト-編集後」と入力し、保存・キャンセルボタンが表示されている)

Step 4⁠:カテゴリ分類機能を追加しよう

編集・削除ができるようになり、メモを自由に管理できるようになりました。しかし、メモが増えてくると今度は別の問題が生じます。仕事のメモと個人のメモが混在して、必要なものをすぐに見つけられなくなるのです。そこで、メモにカテゴリを付けて分類できる機能を追加しましょう。

ここで、第2回で学んだコンテキストの管理を実践します。Step 3までの対話でコンテキストにはメモの編集・削除に関する情報が蓄積されていますが、カテゴリ機能の実装にはこれらの情報は不要です。不要な情報がコンテキストに残っていると、Claude Codeが意図からズレた実装をする原因になります。/clear コマンドを実行してコンテキストをリセットしましょう。

> /clear

これでコンテキストがリセットされました。作業の切り替え時には /clear でコンテキストをリセットする習慣をつけておくと、意図どおりの実装を得やすくなります。

以下のようなプロンプトを送信してカテゴリ機能を追加しましょう。

> メモにカテゴリ機能を追加してください。\
 - カテゴリは「仕事」「個人」「アイデア」の3種類\
 - メモ追加時にカテゴリを選択できる\
 - カテゴリで絞り込みができるフィルタボタンを表示

実装が完了すると、以下のような出力が表示されます。

⏺ 実装完了です。追加した機能の概要:

 カテゴリ選択(メモ追加時)
 - テキスト入力欄の下に「仕事 / 個人 / アイデア」のトグルボタンを配置
 - 選択中のカテゴリがカラーハイライトで分かる

 フィルターボタン
 - 「すべて / 仕事 / 個人 / アイデア」の4ボタンを表示
 - 各ボタンにメモ数のバッジを表示
 - フィルター適用時は空メッセージも「「仕事」のメモがありません」のように変化

 カテゴリバッジ
 - 各メモに色付きバッジを表示(仕事=青、個人=緑、アイデア=黄)

 編集時
 - カテゴリも変更可能(編集エリアにカテゴリ選択ボタンを追加)

実際に操作して確かめてみましょう。指定した指示通り、メモにカテゴリを設定することができ、一覧ではカテゴリが表示されたり、フィルタボタンでカテゴリごとに絞り込みができることを確認します。

  • メモ追加時にカテゴリを選択できる
  • 追加されたメモにカテゴリが表示されている
  • フィルタボタン(仕事・個人・アイデア・すべて)が表示されている
  • フィルタボタンを押すと、該当するカテゴリのメモだけが表示される
カテゴリフィルタ機能を追加したメモ一覧
カテゴリフィルタ機能を追加したメモ一覧(カテゴリ選択、フィルタボタン、仕事・個人カテゴリのメモが表示されている)

Step 5⁠:ローカルストレージでデータを永続化しよう

カテゴリ分類ができるようになり、メモを種類ごとに整理できるようになりました。しかしまだ課題が残っています。ブラウザをリロードしたり、ブラウザを閉じたりすると、追加したメモがすべて消えてしまうのです。

この問題を解決するには、データをブラウザ側に保存しておく仕組みが必要です。そこで使うのがローカルストレージです。ローカルストレージとは、サーバーを用意しなくてもブラウザだけでデータを保存できるWeb APIで、有効期限がなくブラウザを閉じてもデータが残ります。実際の業務アプリではデータベースを使用することがほとんどですが、今回の要件ではデータベースを必要としないので、今回のようにお試しでの開発には最適です。

それでは、ローカルストレージでデータを永続化する機能を追加してみましょう。また別作業に切り替わるため、/clear コマンドを実行してコンテキストをリセットしてからプロンプトを送信します。

> ブラウザを閉じてもメモが残るように、ローカルストレージで保存する機能を追加してください。\
 - メモの追加・編集・削除のたびにローカルストレージに保存\
 - ページを開いたときにローカルストレージからメモを読み込む

実装が完了すると、以下のような出力が表示されます。

⏺ 実装完了です。追加した機能の概要:

 永続化の仕組み
 - App.jsx:8 ̶ useEffect で初回マウント時にメモをローカルストレージから読み込み
 - App.jsx:15 ̶ メモ配列が変更されるたびにメモをローカルストレージに保存
 - JSON.parse / JSON.stringify でオブジェクト配列とJSON文字列を相互変換

 動作フロー
 - 追加・編集・削除 → state更新 → useEffectが検知 → ローカルストレージに自動保存
 - ページリロード → useEffectが初回実行 → ローカルストレージから復元

では、ブラウザで操作して、実際にメモが永続化されていることを確認しましょう。

  1. メモをいくつか追加する
  2. ブラウザをリロードする
  3. 先ほど追加したメモが残っていれば成功
ブラウザリロード後もメモが保持されている画面
ブラウザリロード後もメモが保持されている画面(「リロード前に追加したメモ」が残っている)

これでローカルストレージにメモが保存され、ブラウザを閉じても次回アクセス時に自動的に読み込まれるようになりました。

今回使った知識を振り返ろう

5つのステップで、メモアプリが完成しました。各ステップを振り返ると、第1回から第4回で個別に学んだ知識がそれぞれ異なる場面で活きていたことがわかります。

ハンズオンで活用した知識と使った場面
知識 使った場面
複数行入力 \ + Enter(第1回) 各ステップで条件を箇条書きにして伝えた
コンテキストの管理(第2回) コンテキストの仕組みを踏まえ、/clearで作業単位ごとにリセットした
@記法(第2回) Step 3でファイルを指定して指示した
/init(第3回) Step 1でCLAUDE.mdの雛形を生成した
承認モードの切り替え(第1回) Manualモードで始め、ファイル編集のタイミングでAuto-Acceptモードへ切り替えた
パーミッション設定(第4回) Step 1の後にsettings.jsonを作成し、シェルコマンドの承認を効率化した

個別に学んだ知識が、実際の開発では自然に組み合わさって使われていたことが確認できます。

このハンズオンで重要なのは、段階的に指示して確認しながら進めるという開発フローです。

もし最初から「メモの追加・編集・削除ができて、カテゴリ分類もできて、ブラウザを閉じてもデータが消えないメモアプリを作ってください」と一度に指示していたら、意図通りの結果を得るのは難しかったかもしれません。各ステップで動作を確認し、問題がないことを確認してから次に進む。この流れが、Claude Codeを使った開発の基本です。この開発フローは本書の5章でも取り上げます。

第2回で学んだ /clear でコンテキストをリセットしておきましょう。ここまでの対話でコンテキストが圧迫されているため、リセットして新鮮な状態で次の対話を始めるのが適切です。

> /clear

メモアプリをGitで管理しよう

アプリが完成したので、コードをGitリポジトリに登録しておきましょう。

> メモアプリのディレクトリをGitリポジトリとして初期化して、すべてのコードをコミットしてください

Claude Codeがリポジトリの初期化(git init)とコミットを実行します。Viteがプロジェクト作成時に.gitignoreを生成しているため、node_modulesやdistは自動的に除外されます。

本書のこの後のハンズオンでは、区切りのよいタイミングでコミットしながら進めます。

まとめ

Claude Codeを使って、5つのステップでReactメモアプリを構築しました。第1回で学んだ複数行入力、第2回の@記法、/clearや第3回の /init、第4回のパーミッション設定など、これまでの連載で学んだ知識を実際のアプリ開発に活用できることを確認できました。コードを書かずに、対話と確認を繰り返すだけでアプリが完成する流れを通じて、AI駆動開発の基本的なサイクルを体験できました。

本書『Claude Codeで作って学ぶ AI駆動アプリ開発入門』では、さらに踏み込んだClaude Codeの使い方も解説しています。ぜひこちらもあわせてお読みください。

おすすめ記事

記事・ニュース一覧