AI がどのようにして Web、モバイル、API を同じコードベースから同時に出荷するのを支援するかを、アーキテクチャ、自動化、テスト、落とし穴まで解説します。

「一つのコードベース」が、すべての画面が同じに見えるとか、すべてのプラットフォームがまったく同じ UI フレームワークを使う、という意味ではありません。意味するのは、製品の挙動に関する単一の、バージョン管理された真実のソースがあるということです—Web、Mobile、API は同じコアルールから構築され、同じリポジトリ境界からリリースされ、同じ契約に対してテストされます。
一つのコードベース: ビジネスルール(価格設定、権限、バリデーション、ワークフロー)を1箇所で変更すれば、その変更がすべての出力に流れる場所。プラットフォーム固有の部分は依然存在しますが、それらは共有コアのまわりに薄く存在します。
共有ライブラリ: 複数のアプリが共通パッケージを持つが、各アプリは異なるバージョン、異なる前提でドリフトし、リリースが不一致になりやすい。
コピペ再利用: 最初は速いが、後で高コスト。修正や改善が確実に伝播せず、バグが複製される。
多くのチームが理想論で一つのコードベースを目指すわけではありません。目標は「Web は X、Mobile は Y」という事故を減らすこと、API の遅延変更を減らすこと、予測可能なリリースを実現することです。ある機能が出荷されるとき、すべてのクライアントが同じルールを受け取り、API が同じ意思決定を反映するようにします。
AI はボイラープレート生成、モデルとエンドポイントのワイヤリング、テスト草案、繰り返しパターンのリファクタリング提示が得意です。不整合(例えばクライアント間でのバリデーションの違い)を指摘し、ドキュメント作成を速めることもできます。
人間は依然としてプロダクトの意図、データ契約、セキュリティルール、エッジケース、レビュー・プロセスを定義します。AI は意思決定を加速できますが、それに取って代わることはできません。
小さなチームはまずロジックと API スキーマを共有し、UI はほぼプラットフォームネイティブのままにすることがあります。大きなチームはより厳密な境界、共有テスト、リリース自動化を早期に導入して、多数の貢献者を整合させる傾向があります。
多くのチームは最初から「一つのコードベース」を目指して始めるわけではありません。3つの別々の製品を維持する苦労を経験したあとで、自然にそこに行き着くことが多いのです。
Web、Mobile、バックエンドが別々のリポジトリにある(しばしば異なるサブチームが所有)と、同じ作業がわずかに異なる方法で繰り返されます。バグ修正は3回の修正に、ポリシーの小さな変更(割引の適用方法、日付の丸め、必須フィールド)が何度も再実装・テストされます。
時間が経つとコードベースはドリフトします。エッジケースは「今回だけここで処理」され、別のプラットフォームには古いルールが残る—誰も存在を知らなかった、ドキュメント化されていなかった、またはリリース直前で書き換えるのが危険だった、という理由で。
機能のパリティは、人が気にしないから壊れるのではなく、各プラットフォームが異なるリリース周期や制約を持っているから壊れます。Web は日次で出せても、モバイルはストア審査を待ち、API は慎重なバージョニングが必要です。
ユーザーはすぐに気づきます:
チームは画面を出す最速経路を作ってから「後でちゃんとしたエンドポイントを作る」ことが多く、結果として API が UI に追いつかない場合があります。逆にバックエンドが新しいモデルを先に出してしまい、UI チームが同時に更新しないために、API がクライアントに正しく使われない機能を露出してしまうこともあります。
リポジトリが増えると調整コストが増えます:PR が増え、QA サイクルが増え、リリースノートが増え、オンコールのコンテキストスイッチが増え、同期が外れる機会が増えます。
「一つのコードベース」構成は、製品が「何をするか」と各プラットフォームが「どう届けるか」を分離すると最もよく機能します。最も単純なメンタルモデルは、ビジネスのルールを含む共有コアと、Web、Mobile、API のための薄いプラットフォームシェルです。
┌───────────────────────────────┐
│ Domain/Core │
│ entities • rules • workflows │
│ validation • permissions │
└───────────────┬───────────────┘
│ contracts
│ (types/interfaces/schemas)
┌───────────────┼───────────────┐
│ │ │
┌────────▼────────┐ ┌────▼─────────┐ ┌───▼──────────┐
│ Web Shell │ │ Mobile Shell │ │ API Delivery │
│ routing, UI │ │ screens, nav │ │ HTTP, auth │
│ browser storage │ │ device perms │ │ versioning │
└──────────────────┘ └──────────────┘ └──────────────┘
コアには「合計がどう計算されるか」「誰がリクエストを承認できるか」「何が有効な入力と見なされるか」のようなことを入れます。シェルはそれをプラットフォーム固有の体験に翻訳します。
モバイルはカメラアクセス、プッシュ通知、ディープリンク、生体認証、オフラインストレージポリシーなどのデバイス統合を必要とします。Web はクッキー、URL ルーティング、レスポンシブレイアウト、アクセシビリティパターンのようなブラウザ固有の懸念を持ち続けます。API レイヤーは HTTP 固有の責務(ステータスコード、ページネーション、レート制限、認証フロー)を引き受けます。
接着剤になるのは明示的な契約です:共有型、インターフェース、スキーマ(例えばリクエスト/レスポンスモデルやバリデーションルール)。シェルがこれらの契約を介してコアとやり取りするとき、「どのプラットフォームが正しいか」を巡る議論は減ります。ソースオブトゥルースが共有の挙動であり、各プラットフォームはただそれをレンダリングするだけです。
この構造は共有部分を安定させつつ、各プラットフォームが本当に異なる部分で高速に動けるようにします。
「一つのコードベース」と言うとき、最大の利得は通常 UI ではなく、ビジネスの動作に対する単一の真実のソースを持つことです。つまり、モデル、ルール、バリデーションが一つの共有場所にあり、すべてのクライアント(Web、Mobile、API)がそれに依存するということです。
共有コアには典型的に:
これらのルールが一つのモジュールにあると、古典的なドリフトを回避できます:Web がある合計を表示し、Mobile が別の合計を表示し、API がまた別のルールを強制する、ということが起きません。
AI ベースのツールは、重複が既にある場合に特に有用です。AI は:
重要なのは AI の提案を草案として扱うことです:境界をレビューし、テストを追加し、実際のシナリオで振る舞いを確認します。
ビジネスロジックを共有することは高いレバレッジを持ちますが、UI コードを共有することはしばしばそうではありません。各プラットフォームは異なるナビゲーションパターン、アクセシビリティ期待値、パフォーマンス制約を持つからです。
共有コアは 意思決定とデータ に集中させ、プラットフォームシェルは 表示、デバイス機能、UX を担当させます。こうすることで「万人向けの一つのサイズ」になってしまうのを避けつつ、どこでも挙動を一貫させられます。
「API ファースト」アプローチは、特定の UI を構築する前に API 契約を設計して合意することを意味します。Web アプリがルールを決めてモバイルが「追いつく」代わりに、すべてのクライアント(Web、iOS/Android、内部ツール)が同じ意図的なインターフェースを消費します。
これにより、データ形状、エラーハンドリング、ページネーション、認証に関する決定が一度だけ行われ、各プラットフォームはビジネスルールを再発明せずに独立して前に進めます。
スキーマは API を正確でテスト可能なものにします。OpenAPI(REST)や GraphQL スキーマ を使えば、次のことができます:
スキーマが変わると、CI 内で破壊的変更を検出でき、どのアプリも壊れる前に対処できます。
AI は既存のスキーマ、ドメイン用語、例から作業するときに最も有用です。AI は次の草案を作れます:
鍵はレビューです:AI 出力を出発点として扱い、リントや契約テストでスキーマを強制してください。
AI は「一つのコードベース」環境で、つまらない部分を加速させ、その後は脇に下がるときに最も効果的です。足場のように考えてください:最初の下書きを素早く生成できますが、構造、命名、境界はチームが管理します。
Koder.ai のようなプラットフォームはこのワークフロー向けに設計されています:スペックからチャットでコードを生成し、React Web アプリ、Go + PostgreSQL バックエンド、Flutter モバイルアプリを生成してエクスポートし、通常のメンテナブルなリポジトリとして所有できます。
目標は大きく不透明なフレームワークを受け入れることではありません。目標は既存のアーキテクチャ(共有コア + プラットフォームシェル)に合う小さく読みやすいモジュールを生成し、通常どおり編集・テスト・リファクタできることです。出力がリポジトリ内の平易なコードであれば(隠れたランタイムではなく)ロックインは避けられます—時間をかけて部品を置き換えられます。
共有コードとクライアントシェルについて、AI は次を確実にドラフトできます:
厳密なプロダクト判断は行いませんが、繰り返しのワイヤリングに数時間を節約できます。
AI 出力は次のような具体的な制約を与えると劇的に良くなります:
良いプロンプトはミニスペックとアーキテクチャのスケルトンのように書かれます。
生成されたコードはジュニア開発者のコードのように扱ってください:有益だがチェックが必要です。
こうすれば AI は納品を速めつつ、コードベースの保守性を保てます。
「一つのコードベース」の UI 戦略は、同一のピクセルを目指すのではなく 一貫したパターン を目指すときに最も効果的です。ユーザーはデバイスをまたいでも同じ製品であると認識したいが、各プラットフォームの得意分野は尊重されるべきです。
まず共有しやすい UI パターン(ナビゲーション構造、空状態、読み込みスケルトン、エラーハンドリング、フォーム、コンテンツ階層)を定義します。これらはコンポーネントやガイドラインとして共有できます。
次に、プラットフォームごとの違いを許容します:
目標は:ユーザーが瞬時に製品を認識できること、たとえ画面レイアウトが異なっても。
デザイントークンはブランディングの一貫性をコード化します:色、タイポグラフィ、スペーシング、エレベーション、モーションが名前付きの値になります。
トークンを使えば一つのブランドを維持しつつ:
をサポートできます。
AI はラストマイルの作業を速めるアシスタントとして有用です:
人が承認するデザインシステムを真実のソースにして、AI は実装とレビューを加速するために使ってください。
モバイルは単に「小さい Web」ではありません。オフラインモード、断続的接続、バックグラウンド化を明示的に設計してください。タッチターゲットは親指を想定し、密なテーブルは簡素化し、最重要アクションを上部に配置してください。こうすると一貫性はユーザーの利点になります—制約ではなく。
「モノレポ」とは、関連する複数のプロジェクト(Web アプリ、モバイルアプリ、API、共有ライブラリ)を1つのリポジトリに保持することを指します。エンドツーエンドで機能を更新するために複数のリポジトリを横断する代わりに、共有ロジックとクライアントを1つの PR で変更できます。
価格ルールの変更が API レスポンス、モバイルのチェックアウト、Web の UI に影響するような場合、モノレポは有効です。バージョンの整合を保ちやすく、Web が誤って共有パッケージの「v3」に依存していてモバイルがまだ v2 のまま、という状況を防げます。
とはいえ、モノレポは規律が必要です。境界が曖昧だと誰でも何でも編集してしまいます。
実用的な構成は「apps」と「packages」です:
AI はここでパッケージテンプレート(README、エクスポート、テスト)を生成したり、パッケージの進化に伴ってインポートや公開 API を更新するのを助けられます。
依存は内向きに向かうべきです。例えば:
これをツール(リンター規則、ワークスペース制約)とコードレビューのチェックリストで強制してください。目標は共有パッケージが真に再利用可能であり、アプリ固有コードは局所的に保たれることです。
チームが大きく、リリースサイクルが異なり、厳密なアクセス制御がある場合、複数リポジトリでも機能します。共有パッケージ(コアロジック、UI kit、API クライアント)を内部レジストリに公開してバージョン管理することが可能です。トレードオフは調整コストが増える点です:リリース、更新、互換性の管理に余分な労力が必要になります。
一つのコードベースが Web、Mobile、API を生成する場合、テストは「あればいい」では済みません。1つの回帰が3つの場所で現れ、どこで壊れたかはわかりにくいことが多いです。目標は問題を発生源に近いところで捕まえ、各出力が期待どおりに振る舞うことを証明するテストスタックを構築することです。
共有コードをテストすることに高いレバレッジがあります。
AI は文脈と制約を与えると有用性が高まります。関数署名、期待される振る舞い、既知の失敗モードを与えて次を頼んでください:
テストはレビューしますが、AI は見落としがちな退屈だが危険なケースを見つけるのに役立ちます。
API が変わると Web や Mobile が黙って壊れます。契約テスト(OpenAPI スキーマチェック、コンシューマ駆動契約など)を追加して、API がクライアントの期待を破って出荷されないようにします。
ルールを採用してください:生成コードはテストなしでマージしない。AI がハンドラ、モデル、共有関数を作成した場合、その PR には少なくともユニットカバレッジ(API 形状が変わるなら契約の更新も)を含める必要があります。
「一つのコードベース」から出荷することは、1つのボタンで Web、Mobile、API が完璧に出るという意味ではありません。同じコミットから3つのアーティファクトを生成する単一パイプラインを設計し、何を一緒に動かすべきか(共有ロジック、API 契約)と何を独立させるべきか(アプリストアのロールアウト)を明確にします。
実践的なアプローチは、main ブランチへのマージでトリガーされる単一の CI ワークフローです。そのワークフローは:
AI はここで一貫したビルドスクリプトの生成、バージョンファイルの更新、新しいモジュール追加時の繰り返しワイヤリングの同期を助けます。Koder.ai のようなプラットフォームを使用している場合、スナップショットやロールバック機能が CI パイプラインを補完し、問題のある変更を診断中に素早く状態を戻す手段になります。
環境はブランチではなく構成として扱ってください。同じコードを dev、staging、production に流し、デプロイ時に環境固有の設定を注入します:
一般的なパターンは:PR ごとの一時プレビュー環境、production を模した共有ステージング、本番は段階的ロールアウトの背後にある構成です。チーム用のセットアップガイドが必要なら /docs を、CI オプションやプランを比較するなら /pricing を参照してください。
アプリストア審査でブロックされずに「一緒に出荷」するには、フィーチャーフラグを使ってクライアント間の挙動を調整します。例えば、API に新しいフィールドをデプロイしても、フラグで隠しておき、Web と Mobile が準備できてから有効化する、というやり方です。
モバイルは段階的ロールアウト(例:1% → 10% → 50% → 100%)を使い、クラッシュや主要フローを監視します。Web と API はカナリアデプロイやトラフィック分割で同様の目的を果たします。
ロールバックは面倒でないようにします:
目標は、任意のコミットが正確な Web ビルド、Mobile ビルド、API バージョンにトレースできることです。そうすれば前方にも後方にも安全に操作できます。
単一のコードベースから Web、Mobile、API を出荷するのは強力ですが、失敗モードは予測可能です。目標は「すべてを共有する」ことではなく、「正しいものを境界を明確にして共有する」ことです。
過共有が最大のミスです。チームは速さを優先して UI コード、ストレージアダプタ、プラットフォーム固有のトリックを共有コアに押し込んでしまいがちです。
注意すべきパターン:
AI は多くの再利用可能コードを素早く生成できますが、同時に悪い決定を標準化する恐れもあります。
ほとんどのチームは機能提供を止めて「一つのコードベースに全面移行」することはできません。安全なアプローチは段階的です:安定している部分をまず共有し、プラットフォームの自律性を必要なところに残し、AI を使ってリファクタのコストを下げます。
1) 重複を監査し、最初の共有スライスを選ぶ。 同じであるべきコード(データモデル、バリデーションルール、エラーコード、権限チェック)を探します。これは低リスクの出発点です。
2) 1つの共有モジュールを作る:モデル+バリデーション。 スキーマ(型)、バリデーション、シリアライゼーションを共有パッケージに抽出します。プラットフォーム固有のアダプタは薄く保つ(例:フォームフィールドを共有バリデータにマッピングする)。これで即座に「同じバグが3回発生する」問題を減らせます。
3) API サーフェスの契約テストスイートを追加する。 UI に触る前に、API と共有バリデータに対するテストで挙動を固定します。これが将来の統合の安全網になります。
4) UI ではなくビジネスロジックを次に移す。 価格ルール、オンボーディングステップ、同期ルールのようなコアワークフローを共有関数/サービスにリファクタします。Web と Mobile は共有コアを呼び、API も同じロジックをサーバーサイドで使います。
5) UI は選択的に統合する。 本当に同一であるコンポーネント(ボタン、フォーマット、デザイントークン)だけを共有し、プラットフォーム慣習が異なる場合は別画面を許容します。
AI を使って変更を小さくレビューしやすく保ちます:
Koder.ai のようなツール層でこれを行うと、計画モードはこれらのステップを明示的なチェックリストに変え、生成や移動の前にレビューしやすくなります。
測定可能なチェックポイントを設定します:
実用的な指標で進捗を追跡します:
これは、すべての出力(ルール、ワークフロー、バリデーション、権限など)の挙動について、単一でバージョン管理された真実のソースが存在し、すべてがそれに依存することを意味します。
UI やプラットフォーム固有の統合は引き続き異なり得ます。共有されるのは意思決定と契約であり、それによって Web、Mobile、API が一貫性を保ちます。
共有ライブラリは再利用可能なパッケージですが、各アプリが異なるバージョンを固定したり、異なる前提を持ったり、異なるリリーススケジュールで動くとドリフトが起きます。
真の「一つのコードベース」アプローチでは、コアの挙動への変更が同じソースと同じ契約からすべての出力に流れるようになります。
プラットフォームが異なるリリース頻度で動くためです。Web は日次でデプロイできる一方、モバイルはストア審査を待ち、API は慎重なバージョニングが必要になりがちです。
共有コアと契約を持つことで、「Web は X、モバイルは Y」という状態を減らせます。ルール自体を共有アーティファクトにするのが肝心です—3つ別々に再実装するのではなく。
共有コアに入れるべきはビジネスロジックです:
プラットフォームシェルは UI、ナビゲーション、ストレージ、デバイスやブラウザ固有の処理を担当します。
OpenAPI や GraphQL のような明確でテスト可能な契約(型/インターフェース/スキーマ)を使ってください。
それらを CI で強制(スキーマ検証、後方互換性チェック、契約テスト)すれば、クライアントが期待するものを破る変更は出荷できなくなります。
API コントラクトを UI より先に意図的に設計することです。つまり、すべてのクライアントが同じインターフェースを消費するようにするということ。
実践としては、リクエスト/レスポンスの形、エラーフォーマット、ページネーション、認証について合意してから、型付きクライアントを生成し、ドキュメントとバリデーションをスキーマに合わせて維持します。
AI は繰り返し作業の加速に強みがあります:
しかし、意図・エッジケース・レビューは人間が担い、マージ前にガードレールを適用する必要があります。
単一の変更が共有ロジックや Web/モバイル/API に影響する場合、モノレポは便利です。1つの PR で全体を更新でき、バージョンのずれも防げます。
ただし、モノレポは境界が曖昧だとチーム間で誰でも何でも編集してしまうので、規律が必要です。アクセス制御や独立したリリースサイクルが必須なら、複数リポジトリ+内部パッケージ公開も実用的です。
真の起点である共有部に近いテストを優先します:
さらに、契約テストを入れて API の変更が Web や Mobile を黙って壊さないようにします。
よくある落とし穴は、過共有(プラットフォーム固有のハックがコアに漏れる)、偶発的な結合(コアが UI/HTTP をインポートする)、前提の不一致(オフライン優先と常時接続を混在させる)です。
有効なガードレール: