前書き
私がこの記事を書く理由は、近年、生成AIによる実装が当たり前になりつつあり、AIに対する「指示書」としてのドキュメントが改めて注目されていると感じているからです。その流れの中で、「仕様書駆動開発」という考え方も登場してきました。
自律型のAIエージェントがプロジェクト全体のコードを理解するためには、コードが一つのディレクトリ階層にまとまっている方が都合がよく、その文脈から「モノレポの方がAI時代には有効ではないか」という意見も増えています。
一方で、私自身の経験を振り返ると、モノレポには運用フェーズに入ってから顕在化する欠点が少なくありません。実際、過去のプロジェクトでは、規模の拡大やリリースサイクルの違いに耐えきれず、モノレポを維持できなくなり、マルチレポジトリへ移行したケースを何度も経験してきました。
そうした背景もあり、私はモノレポに対して、どうしても慎重な立場を取っています。
本記事では、こうした経験を踏まえつつ、「なぜモノレポからマルチレポに戻したのか」「どのフェーズでモノレポが破綻しやすいのか」について、実体験ベースで整理していきます。
なぜモノレポからマルチレポに戻したのか?
結論から書くと、モノレポが「悪」だったからではありません。
むしろ、導入初期や一定規模までは、モノレポは非常に強力な構成でした。
しかし、プロジェクトが成長し、チームやリリース形態が変化していく中で、
「モノレポであること」が制約として機能し始めた、というのが実情です。
以下は、私が実際にモノレポからマルチレポへ戻す判断に至った主な理由です。
1. リリースタイミングの違いが運用コストになる
モノレポでは、すべてのプロダクトが同一のリポジトリ・履歴・CI/CDパイプラインを共有します。
これは一見すると管理が楽に見えますが、リリースタイミングがズレ始めると一気に負債になります。
例えば、
- 管理画面は毎週リリースしたい
- APIは安定優先で月1回にしたい
- バッチや内部ツールは不定期
といった状況になると、
- 「この変更は今リリースしていいのか?」
- 「他サービスへの影響をどこまで考慮すべきか?」
- 「不要なコード変更まで一緒にデプロイされないか?」
といった確認コストが、コード変更そのものよりも重くなっていきました。
マルチレポに戻したことで、
リポジトリ = リリース単位 となり、この悩みは大きく減りました。
2. CI/CDが肥大化し、変更の影響範囲が読めなくなる
モノレポでは、CI/CDも当然共通化されます。
初期はメリットですが、時間が経つにつれて以下の問題が出てきました。
- どこを変更してもCIがフルで回る
- 一部のテスト失敗が全体を止める
- 関係ない修正なのにビルド時間が長い
「この変更で、どこまで影響があるのか?」を
人間が毎回考えなければならない状態になってしまいました。
マルチレポに戻すことで、
- CIはリポジトリ単位で完結
- 影響範囲は基本的にそのサービス内
- ビルド時間も大幅に短縮
と、思考コストと待ち時間の両方が改善されました。
3. チーム構成の変化にモノレポが追従できなくなった
モノレポは、
- 少人数
- 同じ技術スタック
- 全員が全体を把握している
という前提では非常に相性が良いです。
しかし、
- チームが分かれる
- 担当サービスが固定化される
- オンボーディングメンバーが増える
といったフェーズに入ると、
「全部見えている」ことが、逆にノイズになります。
結果として、
- 関係ないコードまでレビュー対象になる
- 不要な知識コストが新人に発生する
- 責務の境界が曖昧になる
という状態が生まれました。
マルチレポでは、責務がリポジトリで自然に分離されるため、
チーム構造とコード構造を一致させやすくなります。
4. 「将来分離する前提」の設計が常に付きまとう
モノレポを採用していると、常に次の問いが頭に残ります。
これ、将来レポジトリを分けるとしたらどうなる?
結果として、
- 過剰に抽象化する
- 本来不要な共通化をする
- 「今の最適」より「未来の仮定」を優先する
といった設計判断が増えていきました。
マルチレポに戻すことで、
「今、このサービスとしてどうあるべきか」に集中できるようになったのは、
想像以上に大きなメリットでした。
モノレポに向いているフェーズ
モノレポ自体を否定したいわけではありません。
- 立ち上げ初期
- PoCフェーズ
- 少人数・高速検証
といった場面では、今でも有効な選択肢だと思っています。
ただし、成長フェーズに入ったプロダクトでは「いつか戻す決断」が必要になる可能性が高い、
それを経験則として強く感じています。
モノレポに向いているフェーズ/向いていないフェーズ
モノレポは強力な構成ですが、すべてのフェーズに万能というわけではありません。
重要なのは、「今のプロジェクトがどのフェーズにあるのか」を正しく見極めることです。
ここでは、私の経験をもとに、モノレポが向いているフェーズと向いていないフェーズを整理します。
モノレポに向いているフェーズ
1. 立ち上げ初期・PoCフェーズ
- プロダクトの形がまだ固まっていない
- 仕様変更が頻発する
- とにかくスピードを優先したい
このフェーズでは、モノレポの
- コード共有のしやすさ
- 横断的な修正の速さ
- リポジトリ管理のシンプルさ
が大きな武器になります。
「後で分けるかもしれない」ことを深く考えず、
まずは作って検証することに集中できるのがメリットです。
2. 少人数チーム・フルスタック体制
- メンバー全員が全体を把握している
- 技術スタックがほぼ共通
- レビューや意思決定が速い
この状態では、
- リポジトリをまたぐ認知負荷
- サービス間のバージョン調整
といった問題が発生しにくく、
モノレポの「一体感」がそのまま生産性につながります。
3. リリースサイクルが揃っているフェーズ
- すべてのサービスを同時にリリースできる
- デプロイ頻度がほぼ同じ
- 影響範囲を全員が把握できる
この条件が揃っている間は、
モノレポの共通CI/CDや一括リリースは大きなメリットになります。
モノレポに向いていないフェーズ
1. プロダクト・サービスが増えたフェーズ
- 管理画面、API、バッチ、外部向けSDKなどが混在
- 各サービスの責務が明確に分かれてきた
この状態になると、
- 変更の影響範囲が見えづらい
- 不要なコードまで認知対象になる
といった問題が顕在化します。
モノレポの「全部見える」は、
このフェーズではノイズになりがちです。
2. リリースタイミングがズレ始めたフェーズ
- サービスごとに安定性の要求が異なる
- 一部は頻繁に、一部は慎重にリリースしたい
この状況でモノレポを続けると、
- リリース判断が複雑化する
- デプロイ確認コストが増える
結果として、開発速度そのものが落ちることがあります。
3. チームが分割・専門化されたフェーズ
- チームごとに明確な担当領域がある
- オンボーディングメンバーが増える
- レビューが分業化される
このフェーズでは、
- 責務とコードの境界が曖昧
- レビュー対象が広すぎる
といった問題が起きやすくなります。
マルチレポでは、
リポジトリ = チームの責務 を自然に表現できるため、
組織構造との整合性が取りやすくなります。
4. 「将来分離」を常に意識し始めたフェーズ
- 抽象化や共通化が増え始める
- 設計が過剰に慎重になる
この状態は、
モノレポがフェーズに合っていないサイン だと感じています。
「今の最適」よりも
「将来の仮定」を優先し始めたら、
マルチレポを検討するタイミングかもしれません。
フェーズは固定ではない
重要なのは、
- モノレポ → マルチレポ
- マルチレポ → モノレポ
どちらも間違いではないということです。
プロジェクトのフェーズは必ず変わります。
その変化に合わせて、
リポジトリ構成も柔軟に見直すべきものだと考えています。
モノレポは「正解」ではなく、今そのフェーズに合っているかどうかで判断するものです。
結論:git submoduleによる「ゆるい統合」という選択
モノレポか、マルチレポか。
ここまで整理してきた通り、どちらにも明確なメリット・デメリットがあり、
どちらか一方を絶対解として選ぶのは難しい、というのが私の結論です。
そこで最終的に私が選んだのが、
git上の管理はマルチレポのまま、ドキュメントだけを束ねるという構成でした。
採用した構成の概要
構成としては、以下のようになります。
- 各プロダクト・サービスはそれぞれ独立したリポジトリとして管理
- それらを横断する
- 仕様書
- 設計ドキュメント
- アーキテクチャ図
- AI向けの指示書
を管理する ドキュメント専用リポジトリ を用意
- 各プロダクトリポジトリから、ドキュメントリポジトリを
git submoduleとして参照
つまり、
- コードの責務・リリースは分離
- 理解と参照の起点は共通化
という、いわば「ゆるいモノレポ的構成」を取っています。
なぜgit submoduleを選んだのか
1. リポジトリの独立性を保てる
submoduleは、あくまで参照です。
- 各サービスの履歴は完全に独立
- リリースやCI/CDに影響しない
- submoduleの更新は明示的に行う
この特性により、
- モノレポのように全体が巻き込まれることもなく
- マルチレポのように完全に分断されることもない
ちょうど中間的な立ち位置を取ることができました。
2. ドキュメントを「単一の真実の場所」にできる
ドキュメントを各リポジトリに分散させると、必ず次の問題が起きます。
- どれが最新かわからない
- サービスごとに表現がブレる
- 横断的な設計が見えなくなる
ドキュメント専用リポジトリを作ることで、
- 設計・仕様のSingle Source of Truthを明確化
- 横断的な視点を維持
- AIにも「読むべき場所」を明示
できるようになりました。
3. 生成AI・AIエージェントとの相性が良い
今回この構成を選んだ最大の理由のひとつが、
生成AIとの相性です。
- ドキュメントリポジトリを読み込ませれば
- 全体構成
- 各サービスの責務
- コーディングルール
が把握できる
- コードは必要なリポジトリだけを参照させればよい
結果として、
- 「全部を一つの巨大なコンテキストに入れる」必要がなく
- 理解の起点をドキュメントに集約できる
という構造になりました。
4. フェーズ変化にも耐えやすい
この構成は、
- モノレポに寄せたくなったら
- submoduleを親リポジトリ側に寄せる
- 完全にマルチレポに戻したくなったら
- submoduleを外す
といった可逆性を持っています。
将来の組織・プロダクト変化に対して、
「どちらにも振れる余地」を残せた点は、
精神的にも大きなメリットでした。
運用上の注意点
もちろん、git submoduleにも癖はあります。
- 初回セットアップで混乱しやすい
- submoduleの更新忘れが起きやすい
- CI環境でのcheckout設定が必要
ただし、
- ルールを明文化する
- 更新フローをREADMEに書く
- CIでチェックを入れる
といった対策を取れば、
致命的な問題になることは少ないと感じています。
まとめ
- モノレポか、マルチレポかは二者択一ではない
- ツールでモノポレの一部の欠点は解決できる
- フェーズや目的によって、構成は変えていい
- git submodule + ドキュメント専用リポジトリは
現実的で、可逆性の高い落とし所
特に…
- 生成AIを開発フローに組み込みたい
- リポジトリ構成で悩み続けたくない
というチームにとって、
一度検討してみる価値のある構成だと思っています。