← Blog
Yazı
· 11 dakika· Web Teknolojileri

Monorepo Nedir? Birden Fazla Uygulamayı Tek Repoda Yönetmek

Web sitesi, yönetim paneli ve ortak paketler aynı ürünün parçalarıysa bunları nasıl yönetmeliyiz? Monorepo yapısını, avantajlarını ve maliyetlerini gerçek bir örnek üzerinden inceleyelim.

Monorepo Nedir? Birden Fazla Uygulamayı Tek Repoda Yönetmek

Bir ürün geliştirdiğini düşün. Herkese açık bir web sitesi var. Müşteriler için ayrı bir uygulama, şirket içi ekip için bir yönetim paneli de gerekiyor. Üçünde de aynı renkler, bazı ortak bileşenler ve API tipleri kullanılıyor.

İlk başta her uygulamaya ayrı bir Git deposu açmak doğal geliyor. Sonra ortak bir bileşende değişiklik yapıyorsun: Önce paketi güncelle, yayımla, diğer uygulamalardaki sürümü yükselt, uyumluluğu kontrol et... Tek bir değişiklik birkaç repoya yayılıyor.

Monorepo, birbiriyle ilişkili birden fazla uygulama ve paketin kaynak kodunu tek bir Git deposunda yönetme yaklaşımıdır. Fikir basit görünür; asıl mesele uygulamalar arasındaki sınırları ve geliştirme süreçlerini düzgün kurmaktır.

📌 Kısa Tanım

Monorepo: Birden fazla uygulama veya paketi aynı Git deposunda geliştirirsin. Bu uygulamaların aynı sunucuda çalışması, aynı anda yayımlanması veya aynı teknolojiyle yazılması gerekmez.

📁 Monorepo Yapısı Nasıl Görünür?

Bir SaaS ürünü için örnek yapı şöyle olabilir:

product/
├── apps/
│   ├── web/             # Tanıtım sitesi
│   ├── dashboard/       # Müşteri uygulaması
│   └── admin/           # Yönetim paneli
├── packages/
│   ├── ui/              # Ortak arayüz bileşenleri
│   ├── api-client/      # API istemcisi
│   ├── types/           # Paylaşılan tipler
│   └── eslint-config/   # Ortak geliştirme kuralları
├── package.json
└── pnpm-workspace.yaml

Buradaki apps/ son kullanıcının çalıştırdığı uygulamaları, packages/ ise bu uygulamaların kullandığı ortak paketleri temsil ediyor. Bunlar zorunlu klasör isimleri değil; yaygın ve anlaşılır bir düzen.

Örneğin dashboard ve admin paneli aynı @product/ui paketindeki butonu kullanabilir. Butonda bir erişilebilirlik düzeltmesi yapıldığında değişiklik, onu kullanan uygulamalarla aynı PR içinde incelenebilir.

🔗 Ortak Paket Gerçekte Nasıl Kullanılır?

Monorepo'nun faydası yalnızca dosyaları aynı klasörde görmek değil. Uygulamalar ortak paketleri gerçek bir bağımlılık olarak tanımlamalı. pnpm workspace kullanan basit bir örnek:

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"
// packages/ui/package.json
{
  "name": "@product/ui",
  "version": "1.0.0",
  "private": true,
  "exports": {
    ".": "./src/index.ts"
  }
}

// apps/dashboard/package.json
{
  "name": "@product/dashboard",
  "private": true,
  "dependencies": {
    "@product/ui": "workspace:*"
  }
}

workspace:*, bağımlılığın çalışma alanındaki yerel paketten çözülmesini sağlar. Böylece dashboard içinde ortak paketi açık bir bağımlılık olarak kullanırsın. Gerçek projede kaynak dosyasını doğrudan tüketip tüketemeyeceğin veya paketi ayrıca derlemen gerekip gerekmediği, kullandığın framework ve build yapılandırmasına bağlıdır.

⚙️ Araçların Görevleri Farklı

  • pnpm workspace: Çalışma alanındaki paketleri ve bağımlılıklarını yönetir.
  • Turborepo veya Nx: Birden fazla projenin build, test ve benzeri görevlerini düzenlemeye yardımcı olur.
  • Git: Uygulamaların ve paketlerin değişiklik geçmişini aynı depoda tutar.

Her monorepo'nun ilk günden büyük bir görev yönetim aracına ihtiyacı yoktur. İki küçük uygulamada workspace yeterli gelebilir. Proje büyüdüğünde görev bağımlılıkları ve önbellekleme daha değerli hâle gelir.

✅ Monorepo'nun Sağladığı Avantajlar

1. Ortak kodu görünür kılar

Gerçekten ortak olan UI bileşenlerini, tipleri veya araçları paketlere taşıyabilirsin. Her uygulamada aynı değişikliği ayrı ayrı yapmak zorunda kalmazsın.

2. İlişkili değişiklikleri birlikte yaparsın

API istemcisi değiştiğinde onu kullanan uygulamaları da aynı PR içinde güncelleyebilirsin. Değişikliğin etkisi inceleme sırasında daha kolay görülür.

3. Geliştirme kuralları tutarlı olur

Lint, TypeScript ve biçimlendirme kurallarını ortak paketlerle yönetebilirsin. Yeni bir uygulama eklerken her kararı baştan vermen gerekmez.

Örneğin ortak bir para biçimlendirme fonksiyonu hem müşteri ekranında hem yönetim panelinde kullanılıyorsa iki ayrı kopyanın zamanla farklı davranmasını önlemek istersin. Böyle bir paylaşım monorepo için makul bir sebeptir.

⚠️ Peki Maliyeti Ne?

Tek repo kullanmak karmaşıklığı kendiliğinden ortadan kaldırmaz. Bazı kararları daha görünür ve daha önemli hâle getirir.

  • Yanlış paket sınırları: Her şeyi shared içine atarsan bu paket zamanla bütün uygulamaların birbirine bağlandığı bir alana dönüşür.
  • Yavaş CI: Tek bir metin değişikliğinde tüm uygulamaları yeniden derlemek gereksiz zaman harcatır. Değişiklikten etkilenen işleri seçen bir süreç kurman gerekir.
  • Bağımlılık karmaşası: Hangi paketin hangisini kullanabileceği açık değilse döngüsel veya istenmeyen bağımlılıklar oluşabilir.
  • Ortak ayarların etkisi: TypeScript ya da build yapılandırmasındaki tek değişiklik birçok projeyi aynı anda etkileyebilir.
  • Sahiplik: Birden fazla ekip çalışıyorsa hangi uygulama ve paketten kimin sorumlu olduğu belirlenmelidir.

💡 Ortak Paket İçin Basit Bir Ölçüt

“Bu kodu iki yerde kullanıyorum” tek başına yeterli sebep olmayabilir. İki uygulamanın bu kodun gelecekteki değişikliklerini de birlikte paylaşmasını istiyor muyum? sorusunu sor. Cevap hayırsa iki küçük kopya, yanlış kurulmuş bir ortak paketten daha kolay yönetilebilir.

🚀 Tek Repo, Tek Deployment Demek mi?

Hayır. apps/web ve apps/dashboard aynı depoda bulunup ayrı adreslerde, ayrı altyapılarda ve ayrı zamanlarda yayımlanabilir. Hangi uygulamanın ne zaman build edilip yayımlanacağına repo düzeni değil, CI/CD sürecin karar verir.

Örneğin yalnızca tanıtım sitesinin içerikleri değiştiyse dashboard'u yayımlamak istemeyebilirsin. Buna karşılık ortak ui paketindeki bir değişiklik birden fazla uygulamanın doğrulanmasını gerektirebilir. Etkiyi bağımlılık ilişkilerine göre düşünmek gerekir.

🧩 Monorepo ile Microfrontend Aynı Şey mi?

Monorepo kodun nerede ve nasıl geliştirildiğiyle ilgilidir. Microfrontend ise bir arayüzün hangi parçalara bölündüğü, bu parçaların sorumlulukları ve nasıl bir araya geldiğiyle ilgilidir.

  • Monorepo kurup microfrontend kullanmayabilirsin.
  • Microfrontend uygulamalarını ayrı repolarda geliştirebilirsin.
  • İkisini birlikte kullanabilirsin; ancak biri diğerini otomatik olarak sağlamaz.

Aynı şekilde monorepo, uygulamaların tek bir büyük uygulamaya dönüşmesi anlamına da gelmez. Sınırlar ve yayınlama süreçleri doğru kurulduğunda her uygulama kendi sorumluluğunu koruyabilir.

⚖️ Monorepo mu, Ayrı Repolar mı?

Durum Daha Mantıklı Başlangıç
Uygulamalar aynı ürünün parçaları ve sık sık birlikte değişiyor Monorepo
Ortak UI, tipler veya araçlar düzenli olarak paylaşılıyor Monorepo değerlendirilebilir
Projelerin ürün hedefleri ve geliştirme süreçleri birbirinden bağımsız Ayrı repolar
Henüz tek küçük uygulama var, paylaşılacak kod yok Basit bir repo ile başla

Bu tablo kesin bir kural değil. Aynı şirketin bütün projelerini tek repoya toplamak zorunda değilsin. Monorepo sınırını şirket adına göre değil, birlikte değişen ve birlikte yönetilmesi anlamlı olan ürün alanına göre çizebilirsin.

🔮 Ben Olsam Nasıl Başlardım?

İlk günden kapsamlı bir mimari kurmaya çalışmazdım. Önce uygulamaları ve gerçekten ortak olan paketleri belirlerdim:

  1. apps/ altında bağımsız çalıştırılabilir uygulamaları ayırırdım.
  2. packages/ altına yalnızca sahibi ve kullanım amacı belli ortak kodu koyardım.
  3. Uygulamaların ortak paketleri açık bağımlılıklar üzerinden kullanmasını sağlardım.
  4. Her uygulama için ayrı build ve yayınlama adımları tanımlardım.
  5. Repo büyüdüğünde etkilenen projeleri seçme ve görev önbellekleme ihtiyacına göre araç eklerdim.

Böylece monorepo, daha ürün küçükken yüklenen bir araç koleksiyonu yerine, uygulamalar arasındaki gerçek ilişkiyi yöneten bir çalışma düzenine dönüşür.

💡 Sonuç

Monorepo'nun değeri “her şey tek yerde” olmasından gelmiyor. Birlikte değişmesi gereken kodu birlikte yönetirken, bağımsız kalması gereken uygulamaların sınırlarını koruyabilmekten geliyor.

Birden fazla uygulama aynı ürün üzerinde çalışıyor ve ortak kod düzenli olarak değişiyorsa monorepo güçlü bir seçenek. İlişkisiz projeleri sırf tek repo olsun diye birleştirmek ise genellikle yeni bir bakım yükü oluşturur.

Kaynaklar