# Flutter'da State Management 2026: Riverpod vs Bloc vs GetX > Flutter state management cozumlerinin 2026 yilinda pratik karsilastirmasi. Riverpod 3.0, Bloc 9.0 ve GetX gercek kod ornekleri, performans karsilastirmalari ve gecis stratejileriyle degerlendirildi. - Published: 2026-04-02 - Updated: 2026-04-02 - Author: Anthony Fillion-Maillet - Tags: flutter, state-management, riverpod, bloc, getx, dart - Reading time: 10 min --- Flutter'da state management, bir uygulamanin widget'lar arasindaki veri akisini nasil yonettigini tanimlar. 2026 yilinda ekosisteme uc cozum hakim durumda: derleme zamani guvenligi sunan Riverpod 3.0, kurumsal sinif olay izleme kapasitesine sahip Bloc 9.0 ve azalan ancak hala var olan kullanim alani bulunan GetX. Dogru cozumun secimi test edilebilirlik, olceklenebilirlik ve uzun vadeli bakim maliyetlerini dogrudan etkiler. > **Quick Decision Framework** > > Riverpod 3.0, derleme zamani guvenligi ve minimum boilerplate ile cogu proje icin ideal secimdir. Bloc 9.0, olay tabanli denetim izleri gerektiren regulasyona tabi sektorlerde standart olmaya devam etmektedir. GetX, yalnizca gecis butcesi bulunmayan mevcut kod tabanlarinin bakimi icin dusunulmelidir. ## Riverpod 3.0: Derleme Zamani Guvenligi ve Otomatik Yeniden Deneme Riverpod 3.0, Flutter uygulamalarinin state tanimlama ve tuketme bicimine koklü bir degisiklik getirdi. Anotasyon tabanli kod uretimi, bagimlilk hatalarini calisma zamani yerine derleme zamaninda yakalar ve daha once manuel test gerektiren tum bir hata sinifini ortadan kaldirir. Basarisiz olan provider'lar icin otomatik yeniden deneme mekanizmasi, gecici ag hatalarini manuel mudahale olmadan yonetir. Bir provider hesaplamasi basarisiz oldugunda, Riverpod yapilandrilabilir gecikmeyle otomatik olarak yeniden dener ve hata kurtarma boilerplate kodunu azaltir. ```dart // counter_provider.dart import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'counter_provider.g.dart'; // Code generation ensures compile-time safety @riverpod class Counter extends _$Counter { @override int build() => 0; // Initial state void increment() => state = state + 1; void decrement() => state = state - 1; void reset() => state = 0; } ``` `@riverpod` anotasyonu tum provider boilerplate'ini olusturur. Tip uyumsuzluklari, eksik override'lar ve dongusel bagimliliklar derleme sirasinda ortaya cikar. ```dart // user_repository_provider.dart import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'user_repository_provider.g.dart'; @riverpod Future currentUser(Ref ref) async { final authService = ref.watch(authServiceProvider); final userId = authService.currentUserId; // Auto-retry on network failure (Riverpod 3.0) final response = await ref.watch( httpClientProvider, ).get('/api/users/$userId'); return User.fromJson(response.data); } ``` Riverpod 3.0, bir widget ekrandan ayrildiginda provider dinleyicilerini otomatik olarak durdurur; bu, gereksiz hesaplamalari azaltir ve mobil cihazlarda pil omrunu iyilestirir. ## Bloc 9.0: Kurumsal Uygulamalar icin Olay Tabanli Mimari Bloc 9.0, olaylar, state'ler ve is mantigi arasinda katı bir ayrim uygular. Her state degisikligi belirli bir olaya eslestirilir ve regulasyona tabi sektorlerin ihtiyac duydugu denetim izini olusturur. Surum 9.0'daki mount guvenlik kontrolleri, geri cagirmalarin dispose edilmis widget'lar uzerinde calismasini onler. ```dart // authentication_event.dart sealed class AuthenticationEvent {} final class LoginRequested extends AuthenticationEvent { final String email; final String password; LoginRequested({required this.email, required this.password}); } final class LogoutRequested extends AuthenticationEvent {} final class SessionRestored extends AuthenticationEvent { final String token; SessionRestored({required this.token}); } ``` Dart 3 sealed siniflar, olaylar uzerinde kapsamli desen eslestirme garantisi saglar. Derleyici, her olay turune bir handler atanmasini zorunlu kilar. ```dart // authentication_bloc.dart import 'package:flutter_bloc/flutter_bloc.dart'; class AuthenticationBloc extends Bloc { final AuthRepository _authRepo; final TokenStorage _tokenStorage; AuthenticationBloc({ required AuthRepository authRepo, required TokenStorage tokenStorage, }) : _authRepo = authRepo, _tokenStorage = tokenStorage, super(AuthenticationInitial()) { on(_onLoginRequested); on(_onLogoutRequested); on(_onSessionRestored); } Future _onLoginRequested( LoginRequested event, Emitter emit, ) async { emit(AuthenticationLoading()); try { final token = await _authRepo.login( email: event.email, password: event.password, ); await _tokenStorage.save(token); emit(AuthenticationSuccess(token: token)); } catch (e) { emit(AuthenticationFailure(message: e.toString())); } } Future _onLogoutRequested( LogoutRequested event, Emitter emit, ) async { await _tokenStorage.clear(); emit(AuthenticationInitial()); } Future _onSessionRestored( SessionRestored event, Emitter emit, ) async { emit(AuthenticationSuccess(token: event.token)); } } ``` Her olay handler'i acik bir state gecisi uretir. Loglama middleware'i, hata ayiklama veya uyumluluk amaciyla her olayi kaydedebilir. Bloc 9.0'daki `EmittableStateStreamableSource` arayuzu, hafif mock uygulamalari olusturmayi mumkun kilarak test surecini basitlestirir. ## Bloc Olay Transformerlari: Yuksek Frekanslı Giris Yonetimi Bloc, yaygin esaomanlilik problemlerini cozen yerlesik olay transformerlari saglar. Yazarken arama, hizli buton tiklamalari ve gercek zamanli veri akislari, bildirimsel olay islemeden faydalanir. ```dart // search_bloc.dart import 'package:bloc_concurrency/bloc_concurrency.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class SearchBloc extends Bloc { final SearchRepository _repository; SearchBloc({required SearchRepository repository}) : _repository = repository, super(SearchInitial()) { // restartable() cancels previous search on new input on( _onQueryChanged, transformer: restartable(), ); // droppable() ignores events while processing on( _onResultSelected, transformer: droppable(), ); } Future _onQueryChanged( SearchQueryChanged event, Emitter emit, ) async { if (event.query.length < 3) { emit(SearchInitial()); return; } emit(SearchLoading()); final results = await _repository.search(event.query); emit(SearchLoaded(results: results)); } Future _onResultSelected( SearchResultSelected event, Emitter emit, ) async { emit(SearchNavigating(result: event.result)); } } ``` `restartable()` transformeri, yeni bir giris geldiginde devam eden aramayi iptal ederek eski sonuclarin yeni sonuclarin uzerine yazilmasini onler. `droppable()` transformeri, bir navigasyon islemi devam ederken tekrarlanan tiklamalari yok sayar. ## GetX: Teknik Borc ve Gecis Gerçekleri GetX, hizli prototipleme ve minimum boilerplate sayesinde popülerlik kazandi. 2026 yilinda kutuphane bir bakim kriziyle karsi karsiya: duzenisiz guncellemeler, tek bakimci darboğazi ve Flutter SDK'nin son surümleriyle artan uyumsuzluklar. GetX kullanan uretim uygulamalari, controller yasam dongusu sorunlari ve örtük global singleton'lardan kaynaklanan bellek sızıntılariyla karsilasir. ```dart // counter_controller.dart (GetX pattern) import 'package:get/get.dart'; // Global singleton - difficult to test and scope class CounterController extends GetxController { final count = 0.obs; // Reactive observable void increment() => count.value++; void decrement() => count.value--; // Lifecycle hooks - disposal timing is unpredictable @override void onClose() { // Cleanup may not execute reliably super.onClose(); } } // Usage in widget class CounterPage extends StatelessWidget { @override Widget build(BuildContext context) { // Get.put creates a global singleton final controller = Get.put(CounterController()); return Obx(() => Text('${controller.count}')); } } ``` `Get.put()` cagrisi, controller'lari global singleton olarak kaydeder. Karmasik navigasyon akislarinda controller'lar hedeflenen kapsamin otesinde kalici olur ve bellek tuketir. `.obs` reaktif degiskenleri, Flutter'in standart state bildirim sistemini atlatir ve diger paketlerle entegrasyonu guvenilmez kilar. ## GetX'ten Riverpod'a Gecis: Adim Adim GetX kod tabanlarini yoneten ekipler, Riverpod'a gecisi kademeli olarak gerceklestirebilir. Her iki kutuphane ayni projede bir arada var olabilir ve tam bir yeniden yazim gerektirmeden ekran ekran donusum yapilmasina olanak tanir. ```dart // Step 1: Replace GetX controller with Riverpod notifier // Before (GetX) class ProductController extends GetxController { final products = [].obs; final isLoading = false.obs; Future loadProducts() async { isLoading.value = true; products.value = await ProductApi.fetchAll(); isLoading.value = false; } } // After (Riverpod 3.0) @riverpod class ProductList extends _$ProductList { @override Future> build() async { // Auto-retry on failure, auto-pause when off-screen return ProductApi.fetchAll(); } Future refresh() async { ref.invalidateSelf(); } } ``` ```dart // Step 2: Replace widget bindings // Before (GetX) class ProductPage extends StatelessWidget { @override Widget build(BuildContext context) { final ctrl = Get.put(ProductController()); return Obx(() { if (ctrl.isLoading.value) return CircularProgressIndicator(); return ListView.builder( itemCount: ctrl.products.length, itemBuilder: (_, i) => ProductTile(ctrl.products[i]), ); }); } } // After (Riverpod 3.0) class ProductPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final productsAsync = ref.watch(productListProvider); return productsAsync.when( loading: () => const CircularProgressIndicator(), error: (err, stack) => ErrorDisplay(error: err), data: (products) => ListView.builder( itemCount: products.length, itemBuilder: (_, i) => ProductTile(products[i]), ), ); } } ``` Riverpod surumu, yukleme, hata ve veri state'lerini `AsyncValue.when()` araciligiyla acikca yonetir. Global singleton yok, manuel yasam dongusu yonetimi yok ve widget unmount edildiginde otomatik temizleme saglanir. ## Performans Karsilastirmasi: Yeniden Olusturma Verimliligi Yeniden olusturma verimliligi kare hizlarini dogrudan etkiler. Her cozum widget yeniden olusturmayi farkli sekilde ele alir ve fark, yuzlerce oge iceren listelerde olculebilir hale gelir. | Metric | Riverpod 3.0 | Bloc 9.0 | GetX | |--------|-------------|----------|------| | Selective rebuild | `select()` filter | `BlocSelector` | `.obs` per field | | Compile-time safety | Full (code gen) | Partial (sealed classes) | None | | Auto-dispose | Built-in | Manual via `close()` | Unreliable | | Pause when off-screen | Automatic (3.0) | Manual | Not supported | | Event traceability | Provider observer | Full event log | None | | Testing isolation | `ProviderContainer.test()` | `EmittableStateStreamableSource` | Requires `Get.testMode` | | Bundle size impact | ~45KB | ~38KB | ~120KB (includes routing, DI, HTTP) | Riverpod'un `select()` metodu ve Bloc'un `BlocSelector`'u, yalnizca degisen veriye bagli widget alt agacini guncelleyerek cerrahi hassasiyetinde yeniden olusturma saglar. GetX'in `.obs` degiskenleri alan bazinda benzer granularite elde eder, ancak bagimlilk grafiginin derleme zamani dogrulamasini sunmaz. > **GetX Bundle Size** > > GetX; routing, bagimlilk enjeksiyonu, HTTP istemcisi ve state management'i tek bir pakette bir araya getirir. Yalnizca state management kullanan uygulamalar bile 120 KB'lik kutuphanenin tamamini iceri aktarir. Riverpod ve Bloc, tek bir isi iyi yapan odakli paketlerdir. ## Cozumler Arasi Test Stratejileri Test edilebilirlik, buyuyen bir ekiple hangi cozumun olceklendirildigi konusunda genellikle belirleyici faktordur. Her kutuphane test konusuna farkli yaklasir. ```dart // Riverpod test - isolated container import 'package:flutter_test/flutter_test.dart'; import 'package:riverpod/riverpod.dart'; void main() { test('Counter increments', () { final container = ProviderContainer.test(); // Override dependencies for isolation final counter = container.read(counterProvider.notifier); expect(container.read(counterProvider), 0); counter.increment(); expect(container.read(counterProvider), 1); }); } ``` ```dart // Bloc test - event-driven verification import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { blocTest( 'emits [loading, success] on valid login', build: () => AuthenticationBloc( authRepo: MockAuthRepo(), tokenStorage: MockTokenStorage(), ), act: (bloc) => bloc.add( LoginRequested(email: 'dev@test.com', password: 'secure123'), ), expect: () => [ isA(), isA(), ], ); } ``` Riverpod'un `ProviderContainer.test()` metodu her test icin izole bir bagimlilk grafi olusturur. Bloc'un `blocTest` yardimcisi, olay tabanli mimariyle uyumlu olarak kesin state gecis dizilerini dogrular. GetX testi, `Get.testMode = true` ayarlanmasini ve controller yasam dongusunun manuel yonetimini gerektirir; bu durum CI ortamlarinda siklikla kararsiz testlere yol acar. > **Interview Preparation** > > Flutter state management, mobil gelistirici mulakatlari icinde en sik sorulan konular arasindadir. Riverpod, Bloc ve GetX arasindaki odunlesimleri anlamak, mimari olgunlugu gosterir. Her cozumun ne zaman uygun oldugunu ve ne zaman olmadigini aciklama pratiği yapilmalidir. ## Karar Matrisi: Dogru Cozumu Secmek Proje kisitlamalari en iyi uyumu belirler. Ekip buyuklugu, regulasyon gereksinimleri ve mevcut kod tabani karara etki eden faktorlerdir. **Riverpod 3.0**, ekibin derleme zamani guvenligine deger verdigi, projenin otomatik hata kurtarma ile asenkron veri cekme gerektirdigi veya kod tabaninin sifirdan olusturuldugu durumlarda uygundur. Ogrenme egrisi olculu duzeydedir: Provider'a asina olan gelistiriciler dogal bir sekilde gecis yapar. **Bloc 9.0**, projenin regulasyona tabi bir sektorde faaliyet gosterdigi (fintech, saglik), ekibin denetim amaciyla tam olay izlenebilirligi gerektirdigi veya uygulamanin odeme isleme gibi karmasik esaomanli is akislarini yonettigi durumlarda uygundur. Boilerplate maliyeti, olcekte bakım kolayligiyla kendini amorti eder. **GetX**, yalnizca gecis maliyetinin mevcut butceyi astigi mevcut GetX kod tabanlarinin bakiminda uygundur. 2026 yilinda GetX ile yeni projelere baslamak, ilk gunden teknik borc olusturur. [Resmi Flutter dokumantasyonu](https://docs.flutter.dev/data-and-backend/state-mgmt/options) GetX'i onerilen cozumler arasinda listememektedir. Flutter state management desenleri uzerine derinlesmek isteyenler icin [Flutter state management temelleri](/technologies/flutter/interview-questions/state-management-basics) modulu, mulakatlarda test edilen temel kavramlari kapsar. [Provider pattern modulu](/technologies/flutter/interview-questions/provider-pattern), her uc cozumde de gecerli olan bagimlilk enjeksiyonu stratejilerini inceler. ## Sonuc - Riverpod 3.0, kod uretimi araciligiyla derleme zamani guvenligi, basarisiz provider'lar icin otomatik yeniden deneme ve mobil cihazlarda pil tuketimini azaltan duraklatma/devam ettirme destegi saglar - Bloc 9.0, tam denetim kapasitesiyle olay tabanli state gecislerini zorunlu kilar ve regulasyona tabi sektorlerde kurumsal uygulamalar icin standart haline gelir - GetX, 2026 yilinda sporadik guncellemeler ve artan SDK uyumsuzluklariyla bir bakim kriziyle karsi karsiyadir; mevcut GetX projeleri Riverpod'a kademeli gecis planlamalidir - GetX'ten Riverpod'a gecis, her iki kutuphane ayni projede bir arada var olabildiginden, tam bir yeniden yazim gerektirmeden ekran ekran ilerler - Test izolasyonu onemli olcude farklilik gosterir: Riverpod `ProviderContainer.test()` kullanir, Bloc olay dizisi dogrulamasiyla `blocTest` kullanir ve GetX kirilgan global test modu yapilandirmasi gerektirir - Paket boyutu mobil cihazlarda onemlidir: Riverpod (~45 KB) ve Bloc (~38 KB) odakli paketler sunarken, GetX (~120 KB) kullanilmayan ozellikleri bir arada paketler --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/flutter/flutter-state-management-2026-riverpod-bloc-getx