Claude Code × Claude Design で趣味のアプリを作った話

Claude Code × Claude Design で趣味のアプリを作った話

こんにちは、広瀬です。

今年のゴールデンウィークに、ジムで使う筋トレ記録アプリを一人で作りました。スタックは Expo (React Native) + Supabase、開発の相棒はターミナルで動く AI コーディングエージェント Claude Code と、claude.ai 上で UI モックを生成・調整できる Claude Design の二つ。計画・設計・実装・デザイン・アイコン・配布までを、この二つと壁打ちしながら一人で回し切りました。この記事では、その「趣味のプログラミング」の進め方を、実際に投げたプロンプトや使ったツール構成も交えて書いてみます。

業務でコードを書いていると、家に帰ってまでエディタを開く気が起きない、というのは正直あります。それでも趣味でコードを書く時間は意外と取り戻せる、というのが今回の話です。

何を、何で作ったか

題材は「週一回ジムに行く程度」の自分の筋トレ記録です。これまで OneNote にメモするというアナログな方法を取っていたのを、ちゃんとアプリにしました。とりあえずストア公開は目指さず、自分がテストユーザーとして使い込みながら改善していくつもりです。

最終的に落ち着いた技術構成がこちらです。技術選定は Claude Code に相談しながら、開発を進めるなかで一つずつ採用していきました。

領域 技術
フレームワーク Expo SDK 54 / React Native 0.81
言語 TypeScript
ルーティング Expo Router
バックエンド Supabase (Postgres + Auth + RLS)
状態管理 / 永続化 TanStack Query + persist (AsyncStorage) でオフラインファースト
ID 生成 UUID v7 をクライアント側で発行 (オフライン時も INSERT 可能)
配布 EAS ビルド (iOS / Android 両対応)

ジムは電波が弱いことも多いので、オフラインでも記録できることだけは最初に押さえました。細かい設計は使いながら少しずつ詰めていく方針です。記録から計算する指標として e1RM (estimated 1 Rep Max) を入れています。「1 回だけ挙げられる最大重量の推定値」で、たとえば 60kg × 10 回のように複数回挙げた記録から計算して、その日どれだけ強かったかを 1 つの数字で比較できるようにするものです。

実際に作った画面がこちらです。左が日々の記録を振り返る履歴、右が 1 回ぶんのセッションの詳細です。

履歴 セッション詳細
筋トレ記録アプリの履歴画面。日付ごとのトレーニング記録一覧
日々の記録を振り返る履歴画面
筋トレ記録アプリのセッション詳細画面。種目ごとの重量・回数の記録
1 回ぶんのトレーニングのセッション詳細画面

題材は身近な不便から探す

何を作るか、というのは趣味のプログラミングで一番手が止まりやすいところだと思います。「市場性のあるアイデアか」を考え始めると手が動かなくなるので、「自分が今ちょっと困っていること」だけで決めていいと思います。家の片付けを計画したい、冷蔵庫の食材を管理したい、契約中のサブスクの必要度を確認したい——こういった日常の「ちょっとこうしたい」が、そのまま題材になります。

題材さえ決まれば、技術スタックも形も何でも構わないというのも趣味の自由なところです。バッチスクリプトでも、Raspberry Pi の IoT でも、Web アプリでもデスクトップツールでもいい。業務で使い慣れたものでも、業務では試せなかったものをゼロから入れてみるのでもいい。技術選定そのものを遊びにできるのが、趣味のプログラミングの良いところだと思います。

Claude Code と Claude Design でどう作ったか

ここが今回の開発フローの核です。Claude Code が実装と設計相談Claude Design がデザインを担当し、机上のサイクルとジムでのサイクルを二重に回しました。

Claude Code と Claude Design を行き来する開発フローの図

1. 計画は Claude Code に相談する

新しい画面や機能は、まず Claude Code に「次にこういうものを作りたい」と投げて、画面構成・データの持ち方・分割可能なタスクを一緒に組み立てます。たとえばセッション記録画面を作るときは、こんな粒度で相談しました。

週1でジムに行く前提の筋トレ記録アプリを作っている。
セッション中に「種目を選ぶ → セットごとに重量とレップ数を記録する」画面を作りたい。
- オフラインでも記録できること(電波が弱いジムで使う)
- 後で e1RM とボリュームを見返せること
データモデル(テーブル設計)、画面構成、分割できるタスクを提案して。

これに対して Claude Code は、テーブル設計 (記録は上書きせず追加していく方針)、画面とコンポーネントの分け方、キャッシュ設計、といった具体案を理由つきで返してくれます。提案を全部そのまま採用するわけではなく、気になる点はその場で質問したり代案を出してもらったりしながら、納得できたものを一つずつ採り入れていきました。

2. プロジェクト専属の Agent と Skill を育てる

Claude Code には .claude/ 配下に置いた Agent(特定タスク用のサブエージェント)と Skill(その場で読み込ませる手順書・知識)を呼び出せる仕組みがあります。「これ毎回やってるな」と気づくたびに、自前のものを書き足していきました。定義そのものも Claude Code と相談しながら書けます。

最終的に揃ったのがこのあたりです。

名前 種類 役割
expo-runner Agent Expo dev server を起動・監視し、Metro / TypeScript / Expo の警告とエラーを抽出。実機で動かす前のスモークテスト用。
supabase-migrator Agent マイグレーション作成 → SQL 記述 → ローカル DB 適用 → TypeScript 型再生成までを 1 コマンドで完結。
design-auditor Agent Claude Design のモックと React Native 実装の差分を、デザイントークン・画面構成・状態遷移の観点で監査し、OK/NG 表で出力。
frontend-design Skill このアプリの色トークン・スペーシング・共通コンポーネント・落とし穴をまとめた UI ガイド。新しい画面を作る前に自動で読み込まれる。

Skill は Markdown に簡単なフロントマターを付けるだけで、Claude Code が「いつ読むべきか」を判断して自動で参照してくれます。たとえば UI ガイドはこんな書き出しです。

---
name: frontend-design
description: このアプリの UI を実装する時に読む。色トークン・スペーシング・
  既存共通コンポーネント・落とし穴をまとめている。新しい画面やカードを作る前、
  既存スタイルを変える前に参照する。
---
(以下に色トークンや共通コンポーネントの一覧が続く)

description に「いつ使うか」を書いておくと、「新しい設定画面を作って」と頼んだだけで、Claude Code がこの Skill を勝手に開いてから着手してくれます。毎回ゼロから色やスペーシングを説明しなくて済むので、相棒との会話のテンポが軽くなります。スキーマ変更も supabase-migrator に投げれば、マイグレーション作成から型再生成まで一息で終わる。繰り返す手順を切り出していくと、自分のプロジェクト専属のスペシャリストチームが少しずつ揃っていく感覚があります。

3. デザインは Claude Code → Claude Design に橋渡し

計画ができたら、Claude Design に渡すプロンプトを Claude Code に書いてもらいます。計画フェーズの文脈を引き継いだまま、トーン・配色・コンポーネント構成まで詳しく書き起こしてくれるので、自分でゼロから練るより精度が出ます。たとえば「休憩タイマーを手動ボタンから自動開始の常駐バーに変えたい」という曖昧な要望は、Claude Code を通すとこのくらい具体的な仕様まで落ちます。

画面の最下段 (scroll の外、home indicator の上) に sticky な休憩インジケータバーを常駐配置。

─────────────────────────────────────────
 ● 休憩中  1:32  / 2:00     [+30s] [スキップ]
 ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▱▱▱▱▱▱▱▱  ← progress bar
─────────────────────────────────────────

- 背景: rgba(14,14,14,0.96) + backdropFilter: blur(20px)
- 緑ドット (8×8, colors.success) を 1.4s ease-in-out infinite で pulse
- セット完了押下で自動的に休憩タイマー開始、0:00 で SlideOutDown + Haptics

色は colors.success、角丸は --r-lg 16 のように、アプリ側のデザイントークンを参照した形で書いてくれるので、モックと実装の語彙が最初から揃います。これを Claude Design に貼ると、想定に近いモックが返ってきます。

Claude Design が生成するモックは画面まるごとの JSX なのですが、その中から休憩バーに当たる部分を抜き出すとこんなコードになっています。上で指定した --success や pulse アニメーションが、そのままコードに落ちているのが分かります。

{/* 休憩インジケータバー (sticky bottom) */}
<div style={{ backdropFilter: 'blur(20px)', padding: '10px 16px 12px' }}>
  <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:6 }}>
    <span style={{
      width:8, height:8, borderRadius:'50%',
      background:'var(--success)',
      boxShadow:'0 0 0 4px rgba(34,197,94,0.18)',
      animation:'pulse 1.4s ease-in-out infinite',
    }}/>
    <span style={{ fontSize:11, fontWeight:700, color:'var(--text-2)' }}>休憩中</span>
    <span className="num" style={{ fontSize:18, fontWeight:700 }}>1:32</span>
    <span style={{ fontSize:11, color:'var(--text-3)' }}>/ 2:00</span>
    <button>+30s</button>
    <button>スキップ</button>
  </div>
  {/* progress bar */}
  <div style={{ height:3, background:'#1f1f1f', borderRadius:2 }}>
    <div style={{ width:'76%', background:'linear-gradient(90deg, var(--success), #4ade80)' }}/>
  </div>
</div>

モック全体をレンダリングするとこんな画面になり、いま抜き出した休憩バーは下端に表示されています。

Claude Design で生成したセッション中画面のモック。下端に休憩タイマーバー
Claude Design が生成したセッション中画面のモック(下端が休憩バー)

4. 実装は Claude Design → Claude Code に戻す

モックが固まったら、Claude Design の「Share → Handoff to Claude Code」から「Copy Command」を取得します。コピーされるのはこんな形式の文字列です。

Fetch this design file, read its readme, and implement the relevant aspects of the design. https://api.anthropic.com/v1/design/h/xxxx?open_file=Mockups.html
Implement: Mockups.html

これをそのまま Claude Code に貼り付けると、API 経由でデザインファイルをフェッチして、同梱の README を読んだ上で React Native での実装に取りかかってくれます。

モックはすべての画面や状態を網羅しているわけではありません。デザインが用意されていない部分は、こちらが細かく指示しなくても、Claude Code が前後の文脈から判断して勝手に実装してくれます。これで、ひとまず画面が一通り動く状態になります。

5. 確認して、気になるところは Claude Code → Claude Design に戻す

動くものはできていますが、モックとズレていないかを確認します。まず .claude/ に用意した design-auditor という監査用エージェントに、モックのソース (styles.css / screens-*.jsx) と React Native の実装を突き合わせてもらいます。画面ごとに食い違いを表で出してくれるので、ハードコードされた色のズレや、抜けている要素は機械的に洗い出せます。

ただ、これで終わりにはできません。表で OK が並んでいても、実際に動かすと見た目が違う——余白や行間、要素の並び、タップしたときの挙動——といったズレが普通に残ります。なので最後は Expo Go で動かして、モックと見比べながら 1 画面ずつ目視で確認していきました。

確認していると、Claude Code が補った部分に「ちょっと違うな」と感じたり、モックと実装で考え方そのものが食い違っていたりすることがあります。そういうときは Claude Design に戻して直します。たとえば連続記録の表示。モックは「3 日連続!」のような連続日数でしたが、実装は「今週 2/7 日」という週ペース表示になっていました。こういうときは必ずしもモックを正とはせず、どちらが妥当かで決めます。筋トレは中 1〜2 日空けるのが基本なので、連続日数を煽るのはむしろ体に良くない。ここは実装の考え方が正しいと判断して、モックの方を週ペース表示に直すことにしました。

このときに Claude Design へ投げたのが、こんなプロンプトです。「何を・どう変えるか」だけでなく「なぜ」まで添えると、トーンを外したモックが返ってきにくくなります。

ヘッダー右上の「🔥 4日連続」バッジを、週ペース表示に置き換えてください。

Before:  🔥 4日連続
After:   ✓ 今週 4/7   (今週7日のうち4日トレした、の意味)

- アイコン: 炎 → チェック
- 数字部分はモノスペース (.num) で揃える

設計意図:
- 筋トレは中1〜2日空けるのが理想。「連続日数」を強調すると休養が「失敗」に見える
- 月曜に 0/7 にリセットされても「責められる」より「今週もコツコツ」と感じる表示にしたい
- 未達でもネガティブな表現は使わない

返ってきたモックがこちらです。炎の「4日連続」から、チェックの「今週 4/7」へ。同じ緑系でも、煽る指標から「今週もコツコツ」と感じられる指標に変わっています。

ストリーク表示の変更前後。炎の「4日連続」から、チェックの「今週4/7」へ
「4日連続」から「今週 4/7」へ。煽る指標を週ペース表示に変更

機械の監査で大まかな差分を潰し、最後は自分の目で見た目と挙動を合わせ込む。この二段構えのおかげで、モックと実装が少しずつ乖離していくのを防げました。

6. ひと段落ついたらテストとレビューを挟む

一つの画面や機能がだいたい動くようになったら、すぐ次に進まず、いったんテストとレビューを挟みます。AI は速く大量にコードを出してくれるぶん、まとめて最後に確認すると、どこで崩れたのか分からなくなって戻りが大きいからです。

具体的には、コンポーネントや純粋なロジックには Jest のユニット/コンポーネントテストを書き、画面をまたぐ操作は Maestro の E2E(アプリ起動の確認と、「クイック開始でセッションを記録する」という一番よく使う流れ)で通します。といっても自分で全部書くわけではなく、Claude Code に「テスト書いといて」と投げるくらいです。それでも、これまでの文脈を踏まえてロジックにも表示にもテストを足してくれます。レビューにいたっては「レビュー」と打つだけ。あらかじめ登録しておいたレビュー用のコマンドが起動して、変更差分をチェックし、気になる点を挙げてくれます。返ってきた指摘のうち、直すべきものだけ拾う。細かい網羅は AI に任せて、自分は意図と方針だけ見る感じです。テストが緑になった状態を区切りにして、初めて次の機能に進む、というリズムです。

7. アイコンは Claude Design / ChatGPT / Gemini で競わせた

アイコンだけは少し寄り道して、Claude Code に生成プロンプトを書いてもらい、Claude Design・ChatGPT・Gemini の 3 つに同じ条件で投げて比較しました。実際に使ったのがこのプロンプトです。

iOS app icon, 1024x1024, square, no transparency, no text. Dark charcoal
background (#0e0e0e to #1c1c1c subtle gradient). Centered, a soft and rounded
abstract muscle-inspired shape in luminous blue (#1f6feb to #4a8eff gradient).

The shape should be very smooth, plump, and friendly, with gentle curves and
no sharp edges. Slightly asymmetrical and organic, resembling a simplified
shoulder or muscle form but highly abstract and cute.

No internal lines, no symbols, no additional elements.

Subtle inner glow, generous padding (~12%), flat premium vector style, high
contrast, optimized for small size visibility, minimal, modern, friendly,
gender-neutral, app-store quality.

サイズ・背景色・配色・余白といった定量的な指定から、形のニュアンス (plump / friendly / organic / cute) や禁止事項 (no internal lines, no symbols) まで細かく書き起こしてくれたので、同じ条件で 3 つに投げても傾向の違いが見えやすくなりました。

Claude Design ChatGPT (採用) Gemini
Claude Design が生成した筋トレアプリのアイコン案
Claude Design 生成
ChatGPT が生成した筋トレアプリのアイコン案(採用版)
ChatGPT 生成(採用)
Gemini が生成した筋トレアプリのアイコン案
Gemini 生成

最終的に ChatGPT が一番イメージに近かったので採用しました。AI サービスは日々進化しているので、こういう寄り道で何種類か並べてみるのも、趣味だからこそ気楽にできる遊びだと思います。

8. ジムでの実機サイクル

Expo Go での動作が落ち着いたら、EAS の ad-hoc ビルドを作って自分の iPhone に入れ、ジムに持っていきます。実際に使うと「ここに導線がないと不便」「この削除ボタンは間違って押しそう」みたいな気づきが必ず出てくるので、メモをとる。家に帰って Claude Design と壁打ちして改善案を描き、Claude Code に渡して反映する。机上のサイクルと現場のサイクルが二重に回っているイメージです。

AI と組む開発、いまのやり方と聞いてみたいこと

一通り作ってみて、AI と組む開発で「自分はとりあえずこうしている」と言えることが 3 つ出てきました。

  • 毎回説明していることは、AI がいつも読む場所に書いておく。同じ前提を何度も打ち込んでいるなと思ったら、それを Agent / Skill やモックのソースに移す。次からはそれを踏まえて動いてくれるので、指示が短く済みます。
  • モックと実装は、放っておくと必ずズレる。ズレを見つける仕組みと、どちらを正とするか決める自分の目、その両方を用意しておくと、画面が増えても破綻しませんでした。
  • ひと段落ついたらテストとレビューを挟む。AI は速く大量にコードを出すぶん、最後にまとめて確認すると崩れていたときの戻りが大きい。機能が一段落するたびに、コンポーネント単位のテスト (Jest) と画面の通し (Maestro の E2E) を足して、動いている状態を固めてから次に進みました。

とはいえ今はまだ探り探りで、Claude Code と Claude Design のあいだの橋渡しも半分は手作業です。各サービスが進化すれば、こうした連携はいずれもっと簡単に、なめらかになっていくはず。「自分はこうしてる」というのがあれば、ぜひ聞かせてください。

趣味だからこその自由と、業務との距離感

趣味のプログラミングの一番の自由は、評価軸を全部自分で決められることだと思います。技術選定も、完成度の基準も、リリース日も自分次第。しかも業務だと分業される全工程——課題発見も、DB 設計も、実装も、デザインも、配布署名も、QA も——を一人で触れます。普段フロントしか触らなくても、アプリ署名や ad-hoc 配布の落とし穴を短期間で経験できる。これは「手を抜いていい自由」ではなく、どこにこだわってどう作り込むかを自分で決められる自由です。

ただ、これを「業務に役立てるため」と位置付けると、たぶん長続きしません。主目的が業務に寄ると、その技術が業務で使われなくなった瞬間に動機が消えてしまう。作ること自体を楽しむのが主目的で、業務に役立つかもは副次効果、くらいの距離感がちょうどいいのだと思います。

それでも、結果的に業務に効く発見はありました。AI にどこまで任せて、どこから自分で書くか、という肌感を、影響範囲を気にせず試せる場所で先に確かめられたのは大きい。その判断材料が、業務に戻ったときの引き出しになります。

結び

このアプリは、これからもジムでバグを見つけて、家で直して、翌日また使う、という小さなループを回し続けると思います。記録が溜まると新しい種目や機能のアイデアも湧いてきて、トレーニングと開発が地味に刺激し合っているのも、続けられている理由かもしれません。

AI のおかげで開発自体が楽になり、趣味のプログラミングを始めるハードルもぐっと下がっています。Claude Code に計画を相談し、Claude Design でモックを起こし、また Claude Code に戻して実装する——この往復だけでも、一人で全工程を回し切れる時代になりました。みなさんの趣味のプログラミングの話も、ぜひ聞かせてください。