Turborepo monorepoları için opinionated bir üretim referansı — workspace yapısı, iç paketler, görev grafiği tasarımı, önbellekleme, ortam değişkenleri, CI/CD ve deploy stratejileri. Turborepo 2.9 baz alınmıştır. Tutorial değil.
Bu referans, 2022'den bu yana her projede Turborepo çalıştırarak oluşturuldu — iki uygulamalı bir portfolyo monoreposundan 10 uygulama ve 14 paketle 600K LOC'luk bir AI platformuna kadar. Buradaki kalıplar, gerçek kod tabanlarıyla temas halinde hayatta kalanlar.
Her bölüm tek bir soruyu yanıtlar: Bunu üretim için gerçekten nasıl tasarlarım?
Turborepo 2.9 (Mart 2026) kapsar. Önemli yeni özellikler: İlk Göreve Kadar Sürede %96'ya kadar iyileştirme, turbo query kararlı, turbo.jsonc desteği, OpenTelemetry (deneysel), yapılandırılmış loglama (--json, --log-file), 3.0 geçişi için Future Flags.
Bir monorepo, karmaşıklığını yalnızca birden fazla uygulama arasında paylaşılması gereken kodun bulunduğu durumlarda karşılıyor. Uygulamalarınız minimum paylaşılan kodla bağımsız olarak gelişiyorsa, ayrı repolar daha basittir.
Monorepo ne zaman kullanılır:
Yap
Birden fazla uygulama UI bileşenlerini, hook'ları, tipleri veya yardımcıları paylaşıyor
Tek bir PR'ın paylaşılan bir paketi ve tüm tüketicilerini eş zamanlı güncellemesini istiyorsun
Birleşik TypeScript, ESLint ve Prettier yapılandırması istiyorsun
Atomik çapraz paket değişikliklerine ihtiyacın var
Yapma
Uygulamalar gerçekten bağımsız (farklı ekipler, farklı deploy döngüleri)
Tek bir uygulaman var ve daha fazlası için planın yok
Paylaşılan kod bir npm paketi olarak daha iyi olur
Monorepo vergisi: başlangıç kurulum karmaşıklığı, CI yapılandırma yükü ve zaman zaman şaşırtıcı önbellek davranışı. Bunlar gerçek maliyetler — faydaların durumun gerektirdiğinden ağır basıp basmadığı konusunda dürüst ol.
# Uygulamalar — deploy edilir, diğer paketlere kurulmaz
web/
# Next.js frontend
docs/
# Dokümantasyon sitesi
api/
# Backend API
packages/
# Kütüphaneler ve araçlar — uygulamalara ve birbirine kurulur
ui/
# Paylaşılan React bileşenleri
config-ts/
# Paylaşılan TypeScript yapılandırması
config-eslint/ # Paylaşılan ESLint yapılandırması
utils/
# Paylaşılan yardımcılar
package.json
# Kök — workspace tanımı + repo yönetimi devDependencies
turbo.json
# Görev pipeline tanımı
pnpm-workspace.yaml (veya bun.lockb / .npmrc npm/yarn için)
apps/ ve packages/ ayrımı bir kuraldır, zorunluluk değil. Önemli olan: uygulamalar deploy edilir ve diğer paketler tarafından import edilmez; paketler ise uygulamalar ve diğer paketler tarafından import edilen kütüphanelerdir.
packageManager alanı önemlidir — Turborepo bunu paket yöneticisini tespit etmek ve lockfile ayrıştırmayı kararlı hale getirmek için kullanır. Bu olmadan, önbellek geçersiz kılma öngörülemeyen olabilir.
Workspace içindeki iç paketler (kütüphaneler) üç şekilde yapılandırılabilir:
1. Just-in-Time (JIT) / Tüketici Tarafından Derlenen
Build adımı yok. Tüketicinin bundler'ı (Next.js, Vite vb.) TypeScript'i doğrudan derler.
// packages/ui/package.json{ "name": "@repo/ui", "exports": { ".": "./src/index.tsx" // doğrudan kaynağa işaret eder }, "devDependencies": { "typescript": "^5.0.0", "react": "^19.0.0" }}
Artıları: Sıfır build adımı, en hızlı iterasyon, dist/ konusunda endişe yok.
Eksileri: Yalnızca her tüketici TypeScript anlayan bir bundler kullandığında çalışır. Turborepo tarafından önbelleğe alınamaz (build çıktısı yok). TypeScript'te compilerOptions.paths kullanılamaz.
2. Derlenmiş Paket
Kendi build adımı var. Turborepo build çıktısını önbelleğe alabilir.
npm registry çakışmalarını önlemek için bir ad alanı öneki kullan. @repo/ kullanılmayan, talep edilemeyen bir ad alanıdır — yayınlanmayacak iç paketler için ideal.
Paketteki kaynak dosyalar (varsayılan olarak gitignore edilmemiş tüm dosyalar)
Belirttiğin inputs glob kalıpları
env'de listelenen ortam değişkenleri
Global bağımlılıklar (globalDependencies)
Bağımlılık paketlerinden dependsOn çıktıları
Görev tanımının kendisi
Hash önbelleğe alınmış bir girişle eşleşirse: çıktıları geri yükle ve logları anında tekrar çal. Eşleşmezse: görevi çalıştır, ardından sonuçları önbelleğe al.
# CI ortam değişkenleri olarak ayarlaTURBO_TOKEN=vercel-token'inTURBO_TEAM=ekip-slug'in
Kendi barındırma (ducktors/turborepo-remote-cache):
# CI ortam değişkenleriTURBO_API=https://onbellek-sunucun.comTURBO_TOKEN=gizli-token'inTURBO_TEAM=ekibin
Yeni --cache flag'i (2.9'da kullanımdan kaldırılan flag'lerin yerini alır):
# Yerel okuma+yazma, uzak salt okunurturbo build --cache=local:rw,remote:r# Yalnızca uzakturbo build --cache=remote:rw# Önbelleği tamamen devre dışı bırak (--no-cache'in yerini alır)turbo build --cache=local:r,remote:r
Ortam değişkenleri önbellek hash'inin bir parçasıdır. Bir env değişkeni değişirse, önbellek ıskalanır. Env değişkenlerini bildirmeyi unutursan, eski önbellekler elde edersin.
{ "tasks": { "build": { "env": [ "DATABASE_URL", // build'i etkiler → dahil et "NEXT_PUBLIC_APP_URL", // public env, bundle'ı etkiler → dahil et "NODE_ENV" // build davranışını etkiler → dahil et ], "passThroughEnv": [ "CI", // çalışma zamanında gerekli, çıktıyı etkilemez → geçir "VERCEL_URL" // deploy başına değişen URL → geçir ] } }}
env: Bu değişkenlerdeki değişiklikler önbelleği geçersiz kılar.
passThroughEnv: Göreve geçirilir ama önbellek hash'ini etkilemez.
CI sistemleri her çalıştırmada değişen CI_JOB_ID, GITHUB_SHA, BUILD_NUMBER gibi değişkenler ayarlar. Bunları hash'e dahil edersen, hiçbir zaman önbelleğe isabet edemezsin.
Otomatik çıkarımdan CI'ya özel önekleri hariç tutmak için TURBO_CI_VENDOR_ENV_KEY kullan:
# GITHUB_*'ı Turborepo'nun otomatik env çıkarımından hariç tutTURBO_CI_VENDOR_ENV_KEY=GITHUB_
# Tüm paketlerde görev çalıştırturbo buildturbo devturbo lint# Yalnızca belirli paketler için çalıştırturbo build --filter=webturbo build --filter=@repo/uiturbo build --filter=./apps/web# Bir paket ve tüm bağımlılıkları için çalıştırturbo build --filter=web...# Main'e göre değişen paketler için çalıştırturbo build --affected# Bir dizindeki paketler için çalıştırturbo build --filter="./apps/*"
turbo dev # otomatik olarak TUI kullanır# Belirli UI'yı zorlaturbo build --ui=tui # etkileşimliturbo build --ui=stream # geleneksel log akışı (CI için iyi)
TUI'de: paketler arasında gezinmek için ok tuşlarını kullan, paketin loglarına odaklanmak için Enter'a bas, odaktan çıkmak için Ctrl+Z.
GraphQL veya kısayollarla monorepo yapını sorgula:
# Etkileşimli GraphiQL playground'u açturbo query# Mevcut değişikliklerden etkilenen paketler hangileri?turbo query affected# packages/ui'yi değiştirirsem hangi paketler etkilenir?turbo query affected --packages# packages/ui'yi değiştirirsem hangi görevler çalışır?turbo query affected --tasks build# Tüm paketleri listeleturbo query ls# Belirli bir paket için detaylarturbo query ls web# Yalnızca etkilenen paketleri listeleturbo query ls --affected
Yalnızca PR'da değişen paketler için görevleri çalıştır:
- name: Etkilenen görevleri çalıştır run: pnpm turbo build test --affected # Turborepo, GitHub Actions'ta GITHUB_BASE_REF'i otomatik tespit eder # PR head'ini PR base branch'iyle karşılaştırır # Geçmiş mevcut değilse (shallow clone) her şeyi çalıştırmaya geri döner
Önemli:--affected git geçmişine ihtiyaç duyar. Tam geçmiş için fetch-depth: 0 kullan:
- name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 # doğru --affected için tam geçmiş
Not: Bu makine başına önbellek, paylaşılan bir uzak önbellekten çok daha az etkilidir. Ekip genelinde paylaşım için Vercel Uzak Önbelleği veya kendi barındırmalı sunucu kullan.
turbo prune, tek bir uygulama için yalnızca neye ihtiyacı varsa onu içeren seyrek bir workspace oluşturur:
# web uygulaması için kırpılmış workspace oluşturturbo prune web --docker
Çıktı:
out/
json/
# yalnızca package.json dosyaları (bağımlılık kurulum katmanı için)
package.json
apps/web/package.json
full/
# tam kaynak kodu
package.json
turbo.json
apps/web/
FROM node:20-alpine AS base# Kırpılmış workspace'den bağımlılıkları kurFROM base AS installerWORKDIR /appCOPY out/json/ .RUN pnpm install --frozen-lockfile# Tam kaynaktan build etFROM base AS builderWORKDIR /appCOPY --from=installer /app/node_modules ./node_modulesCOPY out/full/ .# Uzak önbellek kimlik bilgileriARG TURBO_TOKENARG TURBO_TEAMENV TURBO_TOKEN=$TURBO_TOKENENV TURBO_TEAM=$TURBO_TEAMRUN pnpm turbo build --filter=web# Üretim imajıFROM base AS runnerWORKDIR /appCOPY --from=builder /app/apps/web/.next/standalone ./EXPOSE 3000CMD ["node", "server.js"]
# İsme göre--filter=web--filter=@repo/ui# Yola göre--filter=./apps/web--filter="./apps/*"# Bağımlıları dahil et (hedefe bağımlı paketler)--filter=web... # web ve bağımlıları--filter=...web # web ve bağımlılıkları# Git değişikliklerine göre--filter="[HEAD^1]" # son commit'te değişen--filter="[main...HEAD]" # main'den itibaren değişen# Etkilenen (akıllı git tespiti)--affected # base ref'i otomatik tespit eder
Son güncelleme: Nisan 2026. Turborepo 2.9 (Mart 2026) kapsar. Önemli özellikler: İlk Göreve Kadar Sürede %96 iyileştirme, turbo query kararlı, turbo.jsonc, OpenTelemetry (deneysel), yapılandırılmış loglama, 3.0 geçişi için Future Flags.