15 puan yazan GN⁺ 2025-06-05 | 4 yorum | WhatsApp'ta paylaş
  • Monorepo benimsemek; organizasyonel tutarlılık, kod paylaşımı ve ortak araç zinciri ortamını güçlendirmek gibi avantajlar sunar, ancak büyük teknoloji şirketlerinin örneklerini olduğu gibi takip etmek yeni sorunlar ve zorluklarla karşılaşmaya yol açar
  • Başarılı bir monorepo için, tüm ana işleri O(repo) değil O(change) haline getirme ilkesine bağlı kalmak gerekir; bunun için build, test ve CI/CD’nin her aşamasında buna uygun araçlar ve stratejiler gereklidir
  • Kaynak kontrolü tarafında başlangıç noktası git’tir; ölçek büyüdükçe sparse checkout, sanal dosya sistemi gibi kademeli genişleme seçenekleri değerlendirilmelidir
  • Build sistemi mümkün olduğunca tek bir dil etrafında tutulmalı, her dilin yerel build araçlarıyla mümkün olduğunca ilerlenmeli, ancak gerçekten gerektiğinde Bazel/Buck2 gibi araçlara kademeli geçiş düşünülmelidir
  • Test ve CI/CD, yalnızca değişiklikten etkilenen kapsamı hızlıca tespit edip build, test ve dağıtım yapabilmelidir; büyük ölçekli monorepo’larda testlerin otomatik yeniden denenmesi, flaky test’lerin izole edilmesi gibi güvenilirlik stratejileri de zorunludur

Giriş: monorepo yolculuğunun başlangıcı

  • Yeni bir Developer Productivity ekibindeki mühendisler için, monorepo benimseme kararı sonrasında hangi hazırlık ve çabanın gerektiği önemli bir soruya dönüşür
  • Google, Meta, Uber gibi büyük şirketlerin iyi görünen örnekleri cazip olsa da, pratikte onlarla aynı düzeyde sonuç üretmek mümkün değildir
  • Her organizasyon, monorepo benimseme kararını kendi gerekçeleri ve ihtiyaçları doğrultusunda vermelidir; bu süreçte tutarlılık (consistency), organizasyonel bütünleşme ve ortak araç kullanımı gibi alanlarda fayda elde edilebilir

Monorepo ihtiyacını netleştirmek

  • Büyük şirket örnekleri, yalnızca sonunda ulaşılan görünümü gösterir; başlangıçta referans alınacak temel gerekçeler olarak uygun değildir
  • Gerçekte yeni sorunlar ortaya çıkar ve mevcut çoklu repo yönetiminden farklı türde meselelerle karşılaşılır
  • Monorepo benimsemenin amacı; tutarlılığı korumak, organizasyon genelinde araçları birleştirmek, mühendislik standartları ile konvansiyonları uygulamaktır
  • Etkili sonuçlar elde etmek için her ekip, kendi kültürüne ve yönüne uygun hedefleri açıkça tanımlamalıdır

Altın kural: O(change) ilkesi

  • Tüm depo ile ilgili araçlar, hızlı çalışabilmek için O(repo) değil O(change) karmaşıklığına sahip olmalıdır
  • Özellikle büyük ölçekli monorepo’lar büyüdükçe, mevcut araçların verimsizliği daha görünür hale gelir; bu nedenle performans sorunlarını aşacak yapısal tasarım zorunludur
  • Büyük şirketlerin teknik bloglarında anlatılan yeniliklerin çoğu da aslında O(repo) kaynaklı verimsizlikleri aşmaya odaklanır

Kaynak kontrolü

  • Çoğu yazılım organizasyonu temel olarak Git kullanır, ancak Git merkezi monorepo ortamında büyük ölçekte genişlediğinde performans sınırlarına ulaşır
    • Gerçekte çoğu organizasyon, git+GitHub ile oldukça uzun süre idare edebilir
  • Büyüme hızlandıkça, sparse checkout (kısmi klon) ve sanal dosya sistemi (gerektiğinde dosyaları sunucudan dinamik indirme) gibi yapılara ihtiyaç duyulur
  • Büyük şirketler buna uyum sağlamak için Git’i fork’lar veya ayrı sistemler geliştirir (Microsoft: kendi Git fork’u, Meta: Mercurial fork’u, Google: Piper vb.)
    • Jujutsu gibi yeni nesil kaynak kontrol sistemleri de değerlendirilebilir
  • Ölçek küçükken Git sorunsuz kullanılabilir, ancak büyüme sürecinde genişleme stratejisini akılda tutmak gerekir
  • Kaynak kodda IDL (Interface Definition Language) ile üretilmiş kod bulunması, depo boyutunun geometrik olarak artması gibi pratik bir sorunu da beraberinde getirir

Build sistemi

  • Bazel, Buck2 gibi araçlar; çok sayıda dili ve karmaşık build grafını destekleyen tipik monorepo build araçlarıdır
    • Güçlüdürler, ancak karmaşıklık ve operasyon yükleri yüksektir
  • Build’i tek bir dilde tutmak hayatı büyük ölçüde kolaylaştırır; ayrıca her dilin kendi build sistemi (ör. Maven, Gradle, Cargo, Go) da yüksek ölçeklenebilirlik sunar
  • Build sisteminin temel görevi, “belirli bir build target’ını verimli biçimde build etmek (verimli artifact üretimi)” ve “değişen dosyalar nedeniyle etkilenen target’ları hızlıca belirlemek”tir
  • Bunun için target determinator (hedef belirleme aracı) kavramı gereklidir; Rust, Go, Bazel gibi ekosistemlerde zaten çeşitli çözümler vardır
  • Remote execution ve caching, pratikte yalnızca çok büyük ölçeklerde gerçekten gerekli olur; sıradan şirketlerde target determination daha kullanışlıdır

Test

  • Her seferinde tüm testleri çalıştırmak verimsiz olduğu için, yalnızca değişiklikten etkilenen alanı test eden bir sisteme ihtiyaç vardır
  • Flaky test’ler, büyük ölçekli test sistemlerinde daha da ciddi bir soruna dönüşebilir
  • Test sistemi; otomatik yeniden deneme, test etki alanını otomatik belirleme ve flaky test’leri izole etme gibi özelliklere sahip olmalıdır
  • Bazı dillerde (ör. Rust’ın nextest, Java’nın JUnit’i vb.) bu gelişmiş özellikler varsayılan olarak ya da eklentilerle sunulur
  • Monorepo’nun test yapısı, etkili olabilmesi için build sistemiyle yakından entegre olmalıdır

Sürekli entegrasyon (CI)

  • CI sistemi, değişikliklere göre gerekli build artifact’larını ve geçerlilik kontrollerini otomatik olarak gerçekleştirmelidir
  • Target determinator performansı ve verimliliği, CI pipeline’ının temel unsurlarından biridir
  • Modern CI, “Merge Queue” gibi çeşitli stratejiler kullanarak kod kalitesini koruma ile birleştirme hızını optimize etme arasında denge kurmalıdır
    • Her tekil commit/PR için tüm doğrulama işlerinin çalıştırılıp çalıştırılmayacağı, yalnızca bir kısmının seçilip seçilmeyeceği ya da birden fazla PR’ın batch halinde işlenip işlenmeyeceği gibi kararlar gerekir
  • Throughput (iş hacmi), Correctness (doğruluk), Tail latency (en uzun bekleme süresi) arasındaki trade-off kurum içinde tanımlanıp tasarlanmalıdır
  • Büyük monorepo’larda birleştirme yönetimi ve CI verimliliğini artırmak hâlâ kusursuz çözümü olmayan zor bir problemdir
  • Rust (bors), Chromium, Uber gibi projeler birbirinden farklı birleştirme/doğrulama stratejileri seçer

Sürekli dağıtım (CD)

  • Monorepo içindeki tüm değişikliklerin atomik olarak dağıtılacağına dair yanılsama, gerçek dünyayla örtüşmez
  • Tek bir PR ile birçok servisin arayüzü, implementasyonu ve client’ları aynı anda değiştirilebilir; ancak gerçek dağıtım (deploy) sonuçta eşzamansız ilerlediği için dağıtım anında sorun çıkabilir
  • Servisler arası contract’ı bozan değişiklikler, dağıtım sırasında ciddi arızalara yol açabilir
  • Etkili bir monorepo CD stratejisi; dağıtım sistemi döngüsü, servis contract doğrulaması ve sorun çıktığında hızlı tespit ile müdahale kabiliyeti gerektirir

Sonuç

  • Monorepo, organizasyonel tutarlılığı ve mühendislik kültürünü güçlendirmek için güçlü bir araçtır, ancak sürekli mühendislik ve araç yatırımı gerektirir
  • Her aşamada O(change) ilkesine uygun otomasyon, araçlar ve kültür inşa etmek esastır
  • Büyümeyle birlikte araçların da sürekli evrilmesi; organizasyon hedeflerini ve kültürünü yansıtan sistematik yönetim çabasının sürdürülmesi önemlidir
  • Yeterli kararlılık, bağlılık ve sürekli yatırım varsa, monorepo sonunda buna değecek bir değer üretir

4 yorum

 
bichi 2025-06-05

Gerçekten çok faydalı bir yazı. Sadece güçlü araçlar değil, gerektiğinde gerekli araçları kendin yapmaya da hazır olmak gerekiyor. Bu yüzden iyi işlerse elde edilen kazanç da büyük oluyor.

 
cosine20 2025-06-05

Yüksek lisans dönemimde danışman hocam, Google çıkışlı bir mühendisle yemek yerken monorepo hakkında bir şeyler duyup gelmiş olacak ki bundan sonra bizim de monorepo ile yönetmemizi önermişti; onu vazgeçirmek için epey uğraşmıştım...
Monorepo’nun iyi yanları çok ama laboratuvarımızın yapısı gereği çıktılarımızı dışarıdaki insanlarla sık sık paylaşmamız gerekiyor; eğer çıktıları monorepo ile yönetiyor olsaydık özellikle bu noktada çok zorlanırdık gibi geliyor. Multi-repo olsa her çıktı için erişim kapsamını ayrı ayrı ayarlamak yeterli çünkü.

 
youngrok 2025-06-05

Monorepo kullanırken yaşanan sıkıntıların çoğu, projelerin zaten fazlasıyla küçük parçalara bölünmüş olmasından kaynaklanıyor gibi görünüyor. Aslında bir ya da iki proje yeterliyken bunu 10 kadar parçaya ayırıp sonra da bunları monorepo olarak birleştirip yönetmeye çalışınca hem monorepo yönetim araçları kullanmak gerekiyor hem de karmaşıklık artıyor. En iyisi projeyi baştan bir ya da iki projede birleştirmek; iki ya da daha fazla proje olsa bile ayrı bir yönetim aracı kullanmak yerine sadece dizinleri ayırıp tek bir depoya koyuyormuş gibi düşünürseniz yönetmek çok daha rahat oluyor.

 
GN⁺ 2025-06-05
Hacker News görüşü
  • Bu başlığı görünce, eskiden "complexity merchants" hakkında yapılan konuşmaları hatırlatan bir deneyim paylaşımı isteği aklıma geldi. Monorepo’ya geçince teknik fedakârlıklar olduğu görüşüne hiç katılmıyorum. Hiyerarşik dosya sisteminin gücünü anlarsanız monorepo’nun değerini de görürsünüz. CI/CD’yi oraya buraya dağılmış yapılandırmalar yerine tek bir monorepo ile kurmak çok daha nettir. Monorepo’nun özü, tüm organizasyonun atomik commit atabilmesidir. Çok sayıda geliştiriciyi koordine ederken bunun faydası ezici düzeydedir. Bir kez rebase etmek ve tek bir büyük toplantı yeterlidir. Ekip üyeleri birbirinden hoşlanmasa ve iş birliği yapmasa bile, yönetim açısından monorepo büyük bir İK aracı işlevi görür.

    • Son dönemde geliştiriciler ayrıştırma, mikroservisler, çok sayıda küçük repo ve monolitten aşırı kaçınma eğiliminde. Bu, karmaşıklığı büyütüp organizasyon yapısı sorunlarını geleceğin teknik sorunlarına dönüştürüyor. Yazılım sistemlerinin iç bağımlılıkları da doğru düzgün fark edilmiyor. Önceki iş yerimde protocol buffer şema dosyalarını güncellerken harcanan zamana hâlâ inanamıyorum. Neyse ki şu anki şirketimde durum böyle değil.

    • Birden fazla projede commit takibi yapmak olsa iyi olur türünde bir şey; bağımlılık takibi ya da downstream test tetikleme açısından pratikte çok büyük fark yaratmıyor. Multi-repo otomasyonuyla da gayet yapılabilir. Monorepo yardımcı olur ama kusursuz değildir ve maliyeti de yüksektir. Dağıtım veya build süreçleri atomik şekilde işlemez. Monorepo ölçeği büyüdükçe git’in dışına çıkıp yeni araçlara ihtiyaç duyarsınız ve bu çok büyük bir iştir. Deneyimi olmayanların kolayca konuşabileceği bir konu değil.

    • Monorepo’nun avantajları kesinlikle var, ama yönetim maliyeti polyrepo’dan daha pahalı. Her durumda monorepo otomatik olarak daha iyi değildir. Ayrıntılı açıklama için şu yazıya bakın. Maliyet/fayda dengesi duruma göre değişir.

    • Programlama ortamı tasarımında faydalı bir kural şu: ekibe ne kadar fazla güç verirseniz, o kadar fazla sorun da çıkma eğilimindedir. Teknik olarak atomik commit daha güçlü bir yetki değil, hatta daha az güçlüdür; ama kötü arayüzlerle çalışmayı mümkün kıldığı için sorun üreten bir güç hâline gelir.

    • Monorepo’ya geçince değişikliklerin daha atomik olduğu inancı bir tuzak olabilir görüşü. [Orijinal alıntı: monorepo’nun en büyük yanılsaması, tüm kod tabanına atomik commit yapılabildiği düşüncesidir. Gerçekte çeşitli dağıtım artifact’leri vardır; servisleri ve istemcileri aynı anda değiştirseniz bile dağıtım asenkron gerçekleşir. Birden fazla repo’da ise iş birden fazla PR ile yapıldığından risk algısı baştan vardır. Monorepo CI ise çoğunlukla servis sözleşmelerini (CI job) doğrulama işlevi görür ve gerektiğinde değişiklik gerekçesinin açıkça belirtilmesini ister.]

  • Büyük teknoloji şirketlerinin monorepo’larında iki tür var. İlki, yazıda anlatılan şirket genelindeki tekil "THE" monorepo; bunun için özel VCS/CI gerekir ve 200 mühendisin desteği gerekir. Google, Meta, Uber bu yöntemi kullanıyor. Bu seviyeye gelene kadar çekilen acı tahmin edilenden çok daha büyüktür ve genelde daha küçük, "takım düzeyi" monorepo’lardan kademeli olarak genişlenir. Her stack/dil/takım kendi tarafını Bazel, Turborepo, Poetry gibi araçlarla yönetir, zamanla bunlar daha büyük bir monorepo’da birleşir. Ama her iki model de hem geliştiriciler hem de iş tarafı için milyonlarca dolar ve milyonlarca saat yatırım ister; nihayetinde de bu süreci yaşamış geliştiricilerin desteğiyle ayakta kalır.

    • Büyük bir monorepo şirketinde çalışmış biri olarak monorepo’yu çok daha fazla tercih ediyorum. Tek bir monorepo, servis grafiğini, kod çağrı yapısını ve genel resmi şeffaf biçimde anlamakta çok yardımcı oluyor. Polyrepo’da bilgi takımlara dağılır, yeni kodu devralmak zorlaşır ve kod arşivini anlamak adeta bir labirentte dolaşmak gibidir. Polyrepo, eski Discord/Slack mesajları gibi unutulup gitmiş hissi verir. Monorepo pahalıysa, polyrepo da öyledir; sadece maliyeti farklı yerden çıkar. Monorepo dev bir kıtanın otoburlusu gibidir, polyrepo ise farklı türlerin karanlığa gömülmesidir.

    • Şu anki şirkette backend yaklaşık 11 git repo’ya bölünmüş durumda ve tek bir özellik için 4-5 merge request gerektiğinden çok zahmetli. Birden fazla projeyi toplamak için monorepo kullanımını değerlendiriyoruz. Ama repo’ları birleştiremiyorsak, monorepo’ya alternatif ne olabilir merak ediyorum.

    • Dilden bağımsız, kolay ve güçlü bir monorepo orkestrasyon sistemi hâlâ yok. Bazel karmaşık ve öğrenmesi zor, ama son dönemde dokümantasyonu çok gelişti. Buck, NX, Pants gibi başka seçenekler de var, fakat her birinin kendine özgü özellikleri var ve özellikle web desteği sınırlı. Çoğu CI bu araçları düzgün desteklemediği için yapılandırması zahmetli. Bu arada Microsoft’un Rush aracı en iyi deneyimi sunuyor; özellikle frontend/NodeJS monorepo’ları için Rush tavsiye edilir Rush resmi sitesi.

    • Monorepo’ların çoğu Google, Uber, Meta gibi devlerin ölçeğine kadar büyümüyor gerçeğinden söz ediliyor. Servis sayısı şirketten şirkete değişir ve çok olsa bile 100 civarındaysa VCS ölçek sorunu çıkmaz; LSP etiketleri de dizüstünde rahatça çalışır. CI’de bütün testleri düşünmeden çalıştırmak bile çoğu zaman makuldür. Sonuç: Her şirketin Google ölçeğine ihtiyacı yok.

    • Şu anki şirket dil stack’lerine göre monorepo kuruyor. Oldukça iyi bir orta yol.

  • Monorepo vs multi-repo tartışmalarında sık geçmeyen bir nokta, "ters Conway yasası" etkisinin ortaya çıkması. Repo yapısı organizasyon yapısını ve sorun çözme biçimini etkiliyor. Monorepo, ortak altyapı ekiplerinde kahramanlık gerektiren işler üretir; ortak alanlara dokunurken potansiyel kırılmalar arttığı için tek bir özelliği geliştirmek bile zorlaşır. Multi-repo’da takımlar arası çok sayıda PR, koordinasyon ve iç siyaset gerekir; ama daha fazla sayıda geliştirici rolleri bölüşüp yükü dağıtabilir.

    • Monorepo’da da merkezi ve derin bağlara sahip bir değişiklikse bunu birkaç aşamaya bölerek uygulayabilirsiniz. O süreçte de birden fazla PR, koordinasyon ve politik meseleyle uğraşmanız gerekir; ama monorepo sayesinde rollout durumunu daha net görebilirsiniz.

    • Polyrepo’da ortak alandaki değişikliklerin downstream repo’lara yansımaması, her repo’nun farklı sürümlere sabitlenmesi ve yıllarca güncellenmeden sorun çıkarması çok daha yaygındır.

    • Organizasyonların en başta repo yapısıyla bir yön belirleyip teknik seçimlerin sonradan geldiği varsayımının doğru olup olmadığı sorgulanıyor. Gerçekte belirli bir repo yapısından daha temel olan, organizasyonun parçalanma mı paylaşım mı eksenindeki felsefi tercihidir. Yön değişse bile kod yönetim biçimi sonradan düzeltilebilir. Multi-repo olsa da mühendisler neredeyse tüm koda erişebilir; monorepo olsa da güçlü izolasyon ve ayrı CI veya dağıtım kuralları uygulanabilir.

    • Monorepo’da projeler arası kolay değişiklik yapılabilmesi, polyrepo’da ise bunun o kadar zahmetli olması nedeniyle birçok şeyin hiç denenmemesi çok daha sık görülür.

  • Büyük teknoloji şirketi deneyimine göre build sistemini yönetmek için başlı başına özel bir ekip gerekiyor. Büyük monorepo’lar, gerektiğinde kaynak dosyalarını indiren sanal dosya sistemi tabanlı yapılar kullanıyor. Yazıda değinilmeyen nokta şu: neredeyse tüm geliştirme, veri merkezinde çalışan development server’larda yapılıyor; 50-100 çekirdekli ortamlar veya isteğe bağlı container’lar kullanılıyor ve bunlar sürekli en son commit’lerle güncelleniyor. IDE, dev server ile entegre; dil veya servise göre ön hazırlık/otomatik kurulumlar da chef/ansible ile otomatikleştiriliyor. Dizüstünde doğrudan büyük ölçekli monorepo geliştirmek çok nadir (istisna: mobil/Mac uygulamaları gibi).

    • Muhtemelen aynı build ekibinde çalışmış biri. Monorepo geliştirme ortamı yerel de olsa uzak da olsa, asıl önemli olan reproducibility. İmajlanan uzak dev server’lar varsa bu hem daha kolay hem daha güvenilir.

    • Küçük ekiplerde de veri merkezi geliştirme ortamı kullanmış biri olarak, bugünün donanım fiyatları ve yoğunluğu düşünülünce kendi rack’inizi kurup dev/staging/test ve diğer isteğe bağlı araçları çalıştırmak çok daha mantıklı. Üretime benzeyen ortak bir geliştirme ortamı paylaşınca monorepo yaklaşımı da çok farklı görünüyor. Ama küçük ve orta ölçekli şirketlerin build sistemine yatırım yapacak gücü olmuyor ve zaten o ölçekte büyük build sistemi sorunları da pek oluşmuyor (en az 10-20 kişi ve çok karmaşık bir ürün olsa bile bakım çoğu zaman part-time yürütülebiliyor).

  • Molnett(serverless cloud) tarafında Bazel tabanlı bir monorepo ile inanılmaz verimlilik yaşadığını anlatan küçük bir ekipten (1,5 tam zamanlı kişi) örnek. Tilt+Bazel+Kind ile tüm platformu ve Kubernetes operator’ünü dizüstünde ayağa kaldırabiliyorlar; hem Mac hem Linux destekleniyor. Bottlerocket tabanlı OS ve Firecracker bile yerelde doğrulanabiliyor. Bir tool layer kurdukları için tüm geliştiriciler aynı sürüm go/kubectl kullanıyor ve yerel kurulum gerekmiyor. Yönetimi emek istiyor ama bunu eski bir Google SRE üyesi sayesinde başarmışlar. Bundan sonra yalnızca bu şekilde çalışmak istediklerini söylüyorlar. (Ana diller Golang, Bash, Rust)

    • 1,5 kişilik bir ekip için tek repo zaten doğal seçim. Bazel deneyimim çok kötüydü ama büyük projelerde değerli olabilir. 2 kişiden küçük ölçekte ise Kind+Tilt tek başına bile yeter. tool layer tarafını da Go zaten go.mod ile bir ölçüde çözüyor. kubectl için de benzeri yapılabilir. Eski bir Googler maaş seviyesinin maliyeti de hesaba katılmalı. Umarım Bazel’in bakım maliyeti ileride de buna değer kalır.

    • Bizim şirkette systemd tabanlı servisler ve ansible playbook’larla dağıtım yapılıyor; tmuxinator ile backend/DB/arama motoru/frontend dahil tüm servisler development modunda tek seferde terminalde otomatik başlatılıyor. Root dizinde tmuxinator komutunu bir kez çalıştırınca tüm development ortamı hazır oluyor. Tek monorepo, öncekine kıyasla ezici derecede daha kullanışlı.

    • Benzer bir durumda Bazel kullanımının etkisini en üst düzeye çıkardıklarını paylaşan biri. tool layer sayesinde development ortamını tutarlı biçimde koruyabildiklerini söylüyor. Şu an doğrudan bazel run kullanmaları gerekiyor ama daha iyi bir otomasyon yöntemi merak ediyorlar. Bunun nasıl çalıştığını anlatmasını istiyorlar.

    • 2 kişilik ekipte mikroservis/K8s kalıplarının başlı başına overengineering olduğu görüşü. Bu kadar küçük bir ekipte hangi yaklaşımı seçerseniz seçin pek sorun olmaz. Eskiden Dropbox/SVN/MS VCS gibi her şeyle de işler yürüyordu (rahatsızlıkları vardı ama ciddi sorun değildi). Bu ölçekte herkes tüm süreci zihninde canlandırabilir. Başarıyı belirleyen şey karmaşık araçlar veya altyapı değil.

  • Son 4 yılda farklı şirketlerde üç kez monorepo kurulumu yapmış bir freelancer’ın deneyimi. Frontend ile sınırlı olarak JavaScript/TypeScript ekosisteminde kaldığı için yönetmesi nispeten kolay olmuş. Gerçekten iyi bir monorepo, içeride polyrepo gibi davranır: her proje bağımsız geliştirilebilir/dağıtılabilir/host edilebilir, ama tek bir kod tabanında birlikte yaşar; ortak bileşenler (UI gibi) serbestçe paylaşılır ve tutarlı bir look-and-feel sağlanır. Pratik rehber olarak şu kaynağı öneriyor.

    • Bu aslında polyrepo değil, monorepo’nun düzgün kurulmuş bir örneği.
  • Sonuçta her şey bağlama bağlı. Bizim şirkette yaklaşık 40 ayrı git repo’su ayrı CI’larla yönetiliyor; build/test/package adımlarından sonra son aşamada birleşik bir dosya sistemi imajı oluşturulup integration test yapılıyor. Bileşenler Flatbuffers mesajlarıyla haberleşiyor ve flatbuffers da submodule olarak yönetiliyor. Downstream bağımlılıkları yönetmek zor olsa da progressive enhancement ile bir miktar esneklik sağlanıyor. Bu yapı multi-repo mu, yoksa çok sayıda submodule içeren bir monorepo mu, bunu teşhis etmek bile zor. Monorepo’ya geçince avantaj elde edilir mi belirsiz. Sonuçta mesele trade-off’lar ve hangi tür rahatsızlıklara katlanmayı seçtiğiniz.

  • Monorepo araçlarıyla ilgili blogun yazarı olarak deneyim paylaşımı. İnsanlar monorepo’nun avantajlarını vurguluyor, ama başarılı bir monorepo işletmenin karmaşıklığını çoğu zaman perde arkasında devops/devtools ekipleri üstleniyor. Bu yüzden geçiş dikkatle değerlendirilmeli; yine de doğru kurulduğunda fazlasıyla değer üretebilir.

  • İyi yönetilen bir monorepo deneyimi o kadar iyi ki başka bir workflow’a dönmek istemezsiniz. Ama hazırlıksız bir "biz de monorepo yapalım" yaklaşımı tam bir kâbus. Eğer hazır bir monorepo ortamını ve araçlarını paket hâlinde satabilseniz, bunun büyük bir iş fırsatı olacağını düşünüyorum.

    • NX zaten tam olarak bu işi yapıyor. Önceki startup’ımda en baştan NX ile geliştirme yaptık ve 15 kişilik Ar-Ge ekibiyle bile 100 kişilik standardizasyon düzeyine ulaştık. Yeni şirkette (startup’ı satın alan tarafta) plansız bir "biz de monorepo" girişimi tam bir felaketti. Şimdi NX’e geçiyoruz ve etkisi çok iyi.
  • Büyük organizasyonlarda monorepo’nun bazen takımlar arası bağımlılıkları aşırı sınırlayıp kod yeniden kullanımını düşürebildiğini yaşamış biri. Bir kütüphane ekibi değişiklik yapmak istediğinde tüm alt kullanıcıların güncellenmesi gerekiyor; üstelik bazı takımlar beklenmedik kullanımlar yaptığı için değişiklikler karmaşıklaşıyor (Hyrum's Law). Sonuçta büyük şirketler iç kopyala-yapıştır, fork’lar, sıkı erişim kontrolleri ve yavaş değişiklik onayları gibi noktalara varıyor.

    • Genel amaçlı kullanılacak bir kütüphane yazarken API tasarımında dikkatli olmak gerekir. Mümkünse API’yi değiştirmeyin; değiştirmek zorundaysanız büyük çaplı değişimi net biçimde planlayın ya da yeni fonksiyon ekleyip eskisini deprecated yapın. Küçük kod parçalarında kopyala-yapıştır da gayet kabul edilebilir.

    • Yine de monorepo’nun güzel tarafı, tüm kullanım yerlerini kolayca bulabilmek ve gerekirse atomik biçimde değiştirip düzeltebilmektir.

    • Tüm yazılımlar bağımlılıkları hesaba katmak zorundadır; monorepo ise hem kütüphane hem kullanıcı tarafında birbirini değiştirebilme yetkisini artırır.

    • Monorepo’da kendi durumunuza göre değişiklik yapmak kolay olduğu için kod yeniden kullanım olasılığı polyrepo’ya göre daha yüksektir.