
AIを「設計パートナー」にして、個人開発のフルスタックテンプレートを作ってみた📖
AIを壁打ち相手にしながら、Web・モバイル・API・インフラまで一通り揃ったフルスタック開発テンプレートを個人開発した話です。何を作ったかに加えて、技術選定やアーキテクチャ設計でAIとどう向き合ったかを振り返ります。
作ろうとしたもの
自分用のフルスタック開発テンプレートです。業務で開発テンプレートを提供される側だった経験から、「自分で作ってみよう」と始めました。
動機は大きく2つあります。
1つ目は、普段の開発で感じていたペインの解消です。
- 採用された技術スタックでどう機能を実現するか、試行錯誤する場面が多かった。そこで、先に動くものを作り、そこから逆算してテンプレート化する方針とした
- DBマイグレーションやCIなど、開発を進める中で追加・改善するケースがあった。実践ベースで、最初から組み込むようにした
- 規模が拡大するにつれて、手元で素早く試行錯誤したくなった。コンテナベースで、ローカルで即座にDBやAPIのテストが完結するようにした
2つ目は個人的な目的です。プライベートで何かを作るとき、毎回ゼロから構成を考えるコストを減らすベースが欲しかったこと。そして、技術選定の経験を積みたかったことです。業務では構成が決まってから入るプロジェクトが多く、選定そのものを経験する機会が少なかったため、自分でやってみることにしました。
できたもの
構想・リポジトリ作成が約1年前、本格的な実装開始が約半年前で、コミット数は1367に達しました。認証、CI/CD(GitHub Actions)、Blue/Greenデプロイまで一通り動く状態です。
構成はTurborepoによるモノレポで、Web(Next.js)・Mobile(Expo)・API(Hono)・Infra(AWS CDK)を1リポジトリで管理しています。
技術スタック
| 領域 | 採用技術 |
|---|---|
| 共通 | TypeScript / pnpm / Turborepo / Biome |
| Web | Next.js(App Router)/ Auth.js(NextAuth)/ Tailwind CSS / shadcn/ui / TanStack Query |
| Mobile | React Native + Expo / Expo Router / NativeWind |
| API | Hono + zod-openapi / bcrypt + JWT(jose)/ pino |
| DB | PostgreSQL / Prisma |
| Infra | AWS CDK / ECS Fargate / RDS / CodePipeline |
APIはHonoにzod-openapiを組み合わせ、サーバーを立ち上げるとSwagger UIが開いてすぐAPIを検証できるようにしています。フォーマッター・リンターはBiomeで統一し、Biomeが対応していないYAMLはPrettierで補完。開発環境はDev Containerで、同じ環境をすぐ再現できます。
バックエンドはOnion Architectureに寄せ、フロントエンドはbulletproof-react構成を採用しました。この2つの経緯は後述します。
3ステップのロードマップ
開発は3ステップで進めています。
- 具体例を作る(完了): デプロイして動くところまで確認し、再現性を確かめる
- 抽象化して汎用テンプレートに(現在地): 過不足なく、具体例を一般化する
- Skillsを整備する(今後): Skills等を整備し、より複雑なアプリケーションを実装する
題材はシンプルなToDoアプリですが、作り込みはリッチにしています。一般的なテンプレートには「実際のプロダクト開発のフローを走り切っていない」「サンプルと実務の間に距離がある」「初期のスピードを優先して拡大時の考慮が不足しがち」という課題があると感じていたため、認証や複数機能を備えて単純なCRUDに留めず、スケールする構成を意識しました。
作るにあたっての設計原則
次の3つを判断基準に置きました。後述するAIとの向き合い方も、すべてこの基準に沿っています。
- スタンダード・ナレッジの多さを重視: 情報が豊富なものを採用し、AIを活かしやすくする
- スケールする構成にする: チームの規模やドメインが増えても耐えられる設計にする
- 実際に調べる・試す・動かす: 机上の比較だけで終わらせず、手を動かして検証する
AIとの向き合い方: 3つの型
振り返ると、今回のAIの使い方は3つの型に整理できました。
- A. 比較させて決める: 複数の判断軸で選択肢を整理させ、自分の状況に当てはめて決定する
- B. 任せて検証する: 提案に一度乗ってみて、実装しながら本当に合うか確かめる
- C. なぜを問い返す: 出てきた答えの理由を掘り下げ、設計判断を自分の言葉にする
A. 比較させて決める
技術選定では、判断軸をAIに与えて選択肢を整理させました。
| 選定対象 | 候補 | 与えた判断軸 |
|---|---|---|
| バックエンドFW | Hono vs NestJS | 設計思想、学習コスト、用途に応じた適正、拡張性、TypeScriptとの親和性、将来性・人気 |
| ORM | Prisma vs Drizzle | 開発体験、柔軟性、スキーマ管理、型安全性、パフォーマンス、将来性・人気 |
| データベース | PostgreSQL vs MySQL | 一般的な利用、機能の豊富さ、ORMの対応状況、柔軟性・厳格さ、将来性・人気 |
壁打ちの流れは「判断軸を与える → AIとの対話で判断軸をブラッシュアップする → 判断軸に沿って評価させる → 自分の状況・背景を追加する → 再検討する」です。一般論の比較で終わらせず、いま自分が何に困っていて、どういう背景でやっているのかを補足したうえで再検討させると、自分の状況に合う理由まで一緒に得られました。
B. 任せて検証する
AIの提案に一度乗って、実装しながらフィット感を確かめた例が2つあります。結果は対照的でした。
うまくいかなかった例: UIライブラリのTamagui
WebとモバイルのUIを統一でき、packages/uiとして再利用しやすいというAIの推奨を受けて採用しました。しかし実際に使ってみると、shadcn/uiに比べてナレッジが少なく初期設定や設計でハマりました。楽をするために採用したはずが、UIライブラリを中心に設計が振り回される逆転現象も起きました。さらに、テンプレートとして使うならモバイルが必須とは限らず、Web・モバイル統一のメリットが噛み合いません。最終的にshadcn/ui(Web)+ NativeWind(Mobile)へ切り替えました。
うまくいった例: パッケージマネージャーのpnpm
モノレポ機能・ディスク効率・Turborepoとの相性が良いという推奨どおり、実際のモノレポ運用でハマりなく機能しました。推奨理由に納得感があったぶん、検証コストも低く済みました。
AIの提案はあくまで参考情報とし、実際に試して検証することで本当にフィットするかどうかを実感をもって判断できます。
C. なぜを問い返す
初歩的なことでも、納得・理解しきれないものは掘り下げました。ディレクトリ構成の提案をそのまま採用せず、理由を問い返した例です。
Q. dbディレクトリをpackagesに配置したのはなぜ? A. 複数アプリからの再利用性/責務の分離/テスト・モックの切り分けのため。
逆に、提案に違和感を覚えて問い返し、軌道修正させたこともあります。リンターの設定をWebとバックエンドで別々に分ける提案が上がってきたときは、こう返しました。
Q. リンターの設定はプロジェクト全体で共通化できるよね? A. その通り。モノレポ全体で共通設定をルートディレクトリに置いて使い回すのが一般的かつおすすめ。
自分が間違っていることもありますが、違和感を放置せず問答を重ねることで、一緒に軌道修正していくパートナーとしてAIを使えました。掘り下げた分だけ、応用の効く知識として残ります。
実例で見る設計の進め方
バックエンド: 段階的にOnion Architectureへ
最初から理想のアーキテクチャを目指すのではなく、動くものから段階的に移行しました。PRを3段階に分けて積み上げています。
- 素朴なCRUDでREST APIを実装
- zodによるバリデーションを導入
- Onion Architectureへ寄せるリファクタリング
最後のリファクタリングでは、値オブジェクトの導入(valueObject.ts/taskStatus.ts/email.ts)、application層を各ドメイン配下のqueryService.tsに整理、infrastructure/prisma・presentation/httpと実装を明示、といった変更を行いました。どこをどう寄せるかはAIとの問答の中で決めています。「動くもの」から意図を持った層分離へ段階的に移行したことで、Onion Architectureの利点を実感を持って理解できました。
フロントエンド: bulletproof-reactの定着
Reactのディレクトリ構成として有名なbulletproof-reactは、名前は知っていたものの実践経験がありませんでした。構造の綺麗さに惹かれて採用を決め、AIに構成を解説してもらいながら進めました。
components/layouts/shadcn/uiから実装を開始し、features/todosやfeatures/settingsといった機能単位の構成を段階的に定着させ、最終的にServer Actions + 型安全なHono RPCクライアントへ統一しています。「知っているだけ」だった知識を、AIと一緒に手を動かすことで実装できるスキルに変えられました。
インフラ: 設計原則を決めてからデプロイ先を比較
インフラは、先に自分で設計原則を決めました。
- 環境を閉じ込めたい: 複数人開発を見据えて
- プロバイダー非依存: 特定クラウドへの依存を避けたい
- サーバーレス回避: 設計難易度が上がり失敗しやすい
この原則からDockerコンテナベースを選択し、デプロイ先の候補をAIに比較整理させました。
| 候補 | 所感 |
|---|---|
| Heroku | 手軽で高速。PaaSなのでコントロールできる範囲は狭い |
| AWS ECS/Fargate(採用) | スケーラビリティ・IaCとの相性が良い |
| Google Cloud Run | 直感的。IAMはシンプルで、ネットワーク周りは暗黙的 |
| Azure Container Apps | 権限管理が厳格。サービスが疎結合で責任境界は明確 |
ただ、AIに特徴を説明されても実感が湧かない部分があったので、寄り道してHeroku・Cloud Run・Container Appsにも実際にデプロイして試しました。リポジトリ作成から本格実装まで半年空いたのは、この検証に時間をかけたためです。回り道でしたが、AIに整理してもらった比較を自分の実感で裏付けられたので、納得して「本番運用のスケーラビリティ・IaCとの相性・制御の自由度」を優先し、AWS ECS/Fargateを選べました。
採用後はAWS CDKで作り込み、network-stack/database-stack/ecr-stack/api-stack/web-stack/pipeline-stackにスタックを分割。RDS PostgreSQLをプライベートサブネットに置き、VPC・ALB・セキュリティグループで構成しています。CodePipelineでDev → Stg → Prodへ昇格し、Blue/Greenデプロイまで組み込みました。業務では機会のなかった「評価軸を自分で選び、技術選定を自分でやる」経験値そのものを得られたのが収穫です。
品質へのこだわり
個人開発でも「複数人開発に耐える」品質基準で作り込みました。
- Lefthook(Gitフック): pre-commitでBiome check・YAML整形・git-secrets・cspell、commit-msgでcommitlint(Conventional Commits準拠のチェック)
- GitHub Actions(CI): ci-api/ci-web/ci-mobile/ci-infra(lint・type-check・test)、ci-yaml-format
- 自動テスト: 単体はVitest(Web/Mobile/API/Packages)、E2EはPlaywright、UIはStorybook
- セキュリティ & 自動更新: git-secretsによるシークレット漏えい防止、Dependabotによる依存パッケージ自動更新
まとめ: AIは答えをくれる道具ではなく、考える叩き台をくれるパートナー
AI活用には、タスクをAIに渡す「代行」としての使い方と、一人の限界を超えて蓄えた知識やアイデアを実現可能にする「能力拡張」としての使い方があります。今回は後者でした。一人では、これだけの技術を組み合わせて完成させることはできませんでした。日頃考えていたアイデアや、技術書などで得た知識を「実現可能」に変えてくれたのがAIです。
AIに書かせるのではなく、自分の「なぜ」に、AIで叩き台を出す。問うのは自分、応えるのがAI、という関係を意識していたからこそ、「比較させて決める」「任せて検証する」「なぜを問い返す」の3つの型に落ち着いたのだと思います。
ここで得た「判断軸を持って技術選定をする」というアプローチは、業務にも活かせる手応えがあります。進行中のプロジェクトにゼロベースの検討をそのまま持ち込むのは難しいものの、選定の考え方や判断基準は実務でも役立っています。
次のステップは、Skillsを整備してこのプロセス自体を再現可能にすることです。みなさんも、AIを壁打ち相手にした個人開発を試してみてはいかがでしょうか!