Boilerplate ve Code Generation Bağımlılığı
Riverpod'un resmi dokümanı tek bir fonksiyon gösteriyor: FutureProvider.autoDispose.family<User, int>((ref, userId) async {...}) — ayrı sınıf, event, state tanımı gerekmiyor. Bloc'ta ise resmi "Core Concepts" örneği seni ayrı bir sealed class CounterEvent, iki alt-event sınıfı ve ayrı bir CounterBloc extends Bloc<CounterEvent, int> sınıfı yazmaya zorluyor. Bu fark kozmetik değil — Bloc mimarisi üç katman öngörüyor, her katman kendi sınıflarını istiyor.
Code generation tarafında yollar ayrılıyor. Riverpod'un resmi SSS'si net: "code generation is completely optional" — ama başka code-gen araçları zaten kullanıyorsan Riverpod'unkini de öneriyor. Bunu riverpod_generator (4.0.9) ile build_runner üzerinden yapabilirsin; istemezsen klasik Provider sözdizimiyle codegen'siz de yazabilirsin. Bloc'ta build_runner tabanlı kod üretimi yok; bunun yerine bloclibrary.dev publisher'ı altında bloc_tools (0.1.0-dev.24) adlı resmi bir CLI var. Ayrıca resmi bloc_lint linter'ı ve iskelet üreten IntelliJ/VSCode eklentileri var.
Kısacası: az kod istiyorsan Riverpod code-gen'i sağlar ama build_runner'a bağımlı kalırsın; Bloc'un event/state zorunluluğu satır sayısını yukarı çeker.
Test Edilebilirlik ve Kurulum Maliyeti
Riverpod'da test yazmak için ekstra bir paket kurman şart değil. Resmi test kılavuzu, ProviderContainer.test() ile izole bir unit test ortamı kurmanı öneriyor; container.read ve container.listen gibi API'ler package:test üzerine doğrudan oturuyor. Yeni bir DSL öğrenmene gerek yok — provider'ı okuyup değerini doğruluyorsun.
Bloc'ta durum farklı. Resmi test kılavuzu seni doğrudan dart pub add dev:test dev:bloc_test komutuna yönlendiriyor ve testlerini blocTest(...) fonksiyonuyla, build/act/expect parametreleriyle yazmanı istiyor. Bu, öğrenilecek ayrı bir API demek — ama karşılığında testlerin, event akışını ve beklenen state dizisini açıkça belgeleyen, okunması kolay bir yapıya kavuşuyor. bloc_test paketi de aktif bakımlı (güncel sürüm 10.0.0).
Senin için pratik sonuç şu: küçük bir ekipte hızlı test yazıp geçmek istiyorsan Riverpod'un "ekstra paket yok" yaklaşımı sürtünmeyi azaltıyor. Ama büyük bir ekipte test kod tabanının tutarlı bir formatta olmasını istiyorsan, blocTest'in dayattığı yapı (her testin build/act/expect üçlüsüyle yazılması) code review'ı kolaylaştırıyor — bu da Bloc'un "disiplini dışarıdan dayatma" karakterinin test katmanına yansıması.
DevTools, İzlenebilirlik ve Öğrenme Eğrisi
İzlenebilirlik tarafında her iki paket kendi felsefesine uygun bir çözüm sunuyor. Riverpod'un DevTools eklentisi riverpod paketinin içinde geliyor: deponun packages/riverpod/extension/devtools/config.yaml dosyası name: riverpod, version: 1.0.0 ve requiresConnection: true alanlarını taşıyor. Dikkat et — bu eklenti riverpod.dev dokümanında anlatılmıyor. Bloc ise ayrı bir DevTools eklentisi yerine, mimari dokümanında öne çıkan BlocObserver deseniyle çalışıyor: her state değişimini tek merkezden loglayabiliyorsun.
Öğrenme eğrisinde Bloc net konumlanıyor: resmi "Why Bloc?" sayfası projeyi "Easy to understand & can be used by developers with varying skill levels" ilkesiyle tanımlıyor. Gerçek yüzeyde bir çelişki var: getting-started akışı beş ayrı kavram öğretiyor — Bloc, Cubit, Event, State, Repository — üstüne bloc_test DSL'i ekleniyor. Riverpod'da tek kavram var: Provider/Ref; dezavantajı klasik ve code-gen syntax arasındaki seçimi sana bırakması.
Ekipte junior ağırlıklıysa ve "yanlış yapamayacakları" bir sözleşme istiyorsan, Bloc'un event/state ayrımı bunu zorunluluk olarak veriyor. Ekip küçükse, Riverpod'un tek-kavram yaklaşımı daha az sürtünmeyle öğreniliyor.
Büyük Uygulamada Ölçeklenme ve Modülerleşme
Bloc'un mimari dokümanı, büyük ve çok ekipli projeler için tasarlanmış bir sözleşme sunuyor: "Bloc-to-Bloc Communication" bölümü, birden fazla Bloc'un birbiriyle nasıl haberleşeceğini resmi olarak tarifliyor, çok-repository ve çok-katman kompozisyonuna izin veriyor. Bu, 10+ geliştiricili bir ekipte "kim hangi state'i nereden değiştiriyor" tartışmasını azaltan, denetlenebilir bir olay akışı sağlıyor.
Riverpod tarafında ölçeklenme farklı bir eksende ilerliyor: daha az boilerplate ile daha çok otomasyon. Riverpod 3.0 ile gelen deneysel mutations özelliği ve resmi riverpod_sqflite paketiyle sağlanan offline persistence, büyüyen bir uygulamanın state yönetimini merkezi bir noktadan otomatikleştirmeyi hedefliyor. Modülerleşme burada "daha fazla sınıf yazarak" değil, "provider grafiğini genişleterek" sağlanıyor — her yeni özellik yeni bir provider, ama event/state ayrımı zorunlu değil.
Kararını verirken şunu sor: ekibin büyüdükçe "kim neyi nasıl değiştirdi" sorusuna resmi bir sözleşmeyle mi cevap vermek istiyorsun (Bloc), yoksa az kodla genişleyen bir provider ağacını mı tercih ediyorsun (Riverpod)?
pub.dev Bakım Sıklığı ve Topluluk Büyüklüğü — Çelişkili Sinyal
Bu kriter sayfanın en özgün bulgusunu barındırıyor çünkü "topluluk büyüklüğü" tek bir sayıya indirgenemiyor — iki metrik tam ters yöne işaret ediyor. GitHub yıldızında Bloc önde: 12.482 yıldız, 3.421 fork, 86 açık issue. Riverpod ise 7.375 yıldız, 1.108 fork, 162 açık issue ile daha küçük bir topluluğa sahip. Bu tabloya bakarsan "Bloc daha popüler" sonucuna varırsın — rakip karşılaştırma yazılarının çoğu tam da burada duruyor.
Ama pub.dev'in canlı sürüm verisi farklı bir hikaye anlatıyor. flutter_riverpod en son 2026-09-03'te 3.4.3 sürümünü çıkarmış; ondan önceki sürümler 2026-07-28 (3.4.2), 2026-07-26 (3.4.1) ve 2026-06-10 (3.3.2) tarihli — yani aylık ile iki aylık arasında değişen, süren bir döngü. flutter_bloc ise en son 2025-05-02'de 9.1.1 sürümüne ulaşmış; 16 aydan uzun süredir yeni bir sürüm almamış. Pub point tarafında da ilginç bir denge var: Bloc 160/160 tam puanla ve "Flutter Favorite" etiketiyle önde, Riverpod 140/160 ile geride — ama indirmede Riverpod ayda 2.970.654 ile Bloc'un 1.876.379'unun önünde.
Sonuç: "hangisi daha popüler" sorusunun tek cevabı yok. Uzun vadeli bakım endişen varsa, yıldızdan çok son sürüm tarihine bak.
Ekipte Mimari Disiplini Dayatma Gücü
Bu son kriter yukarıdaki her şeyi bir araya getiriyor: hangisi ekibine daha fazla dış disiplin dayatıyor? Bloc'un cevabı net — event/state akışı zorunlu, üç katmanlı mimari (Presentation/Business Logic/Data) resmi olarak öngörülüyor, testler blocTest'in build/act/expect üçlüsüne oturuyor ve BlocObserver her state değişimini merkezi olarak loglayabiliyor. Bir geliştirici Bloc'ta "rastgele bir yerden state değiştiremiyor" — mimari buna izin vermiyor.
Riverpod'da disiplin dışarıdan dayatılmıyor, ekibin kendi alışkanlığına bağlı kalıyor. Klasik syntax ile code-gen syntax'ı arasında seçim yapman gerekiyor (resmi doküman bu kararı sana bırakıyor), provider'ları nasıl organize edeceğin (feature-based, layer-based) senin kararın ve state mutasyonunu nereden yapacağın konusunda Bloc'taki gibi bir "duvar" yok. Bu esneklik hız kazandırıyor ama büyük, çok ekipli bir organizasyonda "herkes kendi yolunu seçer" riskini de beraberinde getiriyor.
Pratik özet: dışarıdan gelen bir sözleşmeye ihtiyacın varsa (denetim, uyumluluk, büyük ve dağınık ekip) Bloc bu sözleşmeyi mimarinin kendisine gömüyor. Ekibin zaten disiplinliyse ve hıza öncelik veriyorsan, Riverpod'un esnekliği seni yavaşlatmıyor.