Monorepo mu Polyrepo mu? Büyük Projelerde Depo Stratejileri

Büyüyen bir yazılım organizasyonunda kod depoları yalnızca dosyaların yaşadığı klasörler değildir; ekip sınırlarını, dağıtım hızını ve bağımlılık yönetimini doğrudan etkileyen mimari kararlardır. Monorepo, birçok uygulama ve kütüphaneyi tek Git deposunda toplarken; polyrepo yaklaşımı her servis, uygulama veya bileşen için ayrı depo kullanır. Doğru tercih, moda olan aracı seçmekten çok ürününüzün değişim ritmini anlamaktır.

``

Temel fark: paylaşım mı, izolasyon mu?

Monorepo’da örneğin web arayüzü, mobil uygulama, API, tasarım sistemi ve ortak yardımcı paketler aynı sürüm geçmişini paylaşır. Böylece bir API sözleşmesini değiştiren geliştirici, istemciyi de aynı pull request içinde güncelleyebilir. Polyrepo’da ise bu bileşenler bağımsız depolardır; her biri kendi erişim politikalarına, sürümleme sürecine ve yayın döngüsüne sahiptir.

Basit bir maliyet modeliyle kararın mantığını görünür kılabiliriz:

\[C = C_{build} + C_{coordination} + C_{dependency}\]

Monorepo çoğu zaman $C_{coordination}$ ve $C_{dependency}$ değerlerini azaltır; ancak büyük depo, güçlü CI altyapısı yoksa $C_{build}$ değerini artırabilir. Polyrepo ise bağımsız derleme ve yayın sayesinde belirli projelerde derleme maliyetini düşürür, fakat sürümler arası koordinasyon maliyetini büyütebilir.

Ölçüt Monorepo Polyrepo
Kod paylaşımı Çok kolay, doğrudan import Paket yayınlama veya Git bağımlılığı gerekir
Bağımsız dağıtım Araç ve kuralla sağlanır Doğal olarak güçlüdür
Erişim kontrolü İnce ayar daha zordur Depo bazında nettir
Büyük çaplı refactor Tek değişiklik setinde yapılır Birden fazla sürüm ve PR gerekir
CI gereksinimi Akıllı önbellek ve etki analizi önemlidir Daha basit, fakat çok sayıda pipeline vardır

monorepo-mu-polyrepo-20

Monorepo ne zaman parıldar?

Ortak tiplerin, bileşenlerin ve iş kurallarının sıkça değiştiği ürün ekiplerinde monorepo güçlüdür. Özellikle TypeScript tabanlı bir web platformunda apps ve packages ayrımı, paylaşımı düzenli hale getirir:

repository/
├── apps/
│   ├── web/
│   └── api/
├── packages/
│   ├── ui/
│   ├── types/
│   └── config/
└── package.json

Bu yapı, packages/types içindeki bir sözleşme değiştiğinde hem API hem web uygulamasının aynı commit’te doğrulanmasını sağlar. Ancak herkesin her klasöre dokunabilmesi kaos yaratabilir. Bu yüzden CODEOWNERS, klasör bazlı testler, etkilenen paket analizi ve uzak önbellek gibi pratikler lüks değil, zorunluluktur. Nx, Turborepo, Bazel veya Pants gibi araçlar burada devreye girer.

Örneğin yalnızca değişen pakete bağlı uygulamaları test etmek için pipeline mantığı şu hedefe yaklaşmalıdır:

# Araçtan bağımsız fikir: sadece etkilenen hedefleri çalıştır
npm run test -- --affected
npm run build -- --affected

Amaç her commit’te tüm dünyayı yeniden derlemek değil, değişimin etki grafiğini hesaplamaktır.

Polyrepo ne zaman daha sağlıklı?

Farklı ekiplerin farklı müşterilere, güvenlik alanlarına veya yayın takvimlerine hizmet verdiği yapılarda polyrepo temiz bir sınır oluşturur. Örneğin ödeme servisi, makine öğrenmesi platformu ve pazarlama sitesi aynı anda değişmek zorunda değilse ayrı depolar operasyonel bağımsızlık sağlar. Her depo kendi semantic versioning politikasını uygulayabilir: $MAJOR.MINOR.PATCH$.

Senaryo Daha uygun yaklaşım Neden
Ortak UI ve tiplerin sık değişmesi Monorepo Atomik değişiklik ve hızlı refactor
Güvenlik açısından ayrık ekipler Polyrepo Yetki ve erişim sınırları
Çok sayıda küçük, bağımsız servis Polyrepo Ayrı yayın ve yaşam döngüsü
Tek ürün etrafında çalışan ekipler Monorepo Ortak görünürlük ve standartlar

Kararı araç değil, akış versin

Monorepo, mikroservis kullanamayacağınız anlamına gelmez; çalışma alanı ile dağıtım birimi farklı kavramlardır. Benzer biçimde polyrepo da paylaşımı yasaklamaz; yalnızca paylaşımı paket sözleşmeleri üzerinden daha disiplinli hale getirir. Başlangıçta ekip küçük ve ürün sınırları belirsizse monorepo geliştirme hızını artırabilir. Ekipler ve güvenlik gereksinimleri olgunlaştıkça polyrepo ya da hibrit bir model mantıklı olabilir.

En iyi strateji, geliştiricinin bir değişikliği üretime taşıma süresini, yani yaklaşık $Lead\ Time = Review + Build + Test + Deploy$ değerini düşürendir. Depo düzeninizi bu metrikle ölçün; çünkü klasör yapısından daha önemli olan, değişimin güvenle akabilmesidir.

Yorumlar