name: riverpod description: "Use when working with Flutter Riverpod state management. Covers providers, consumers, refs, containers, overrides, async state, code generation, testing, and safe defaults." metadata: revision: 1 updated-on: "2026-04-04" source: official tags: "flutter,dart,riverpod,flutter_riverpod,providers,async,testing,codegen"
Flutter Riverpod State Management
Use this skill when building Flutter state management with riverpod and flutter_riverpod.
Core Rule
- Use
Providerfor read-only values and dependency wiring. - Use
StateProviderfor small mutable state. - Use
FutureProviderfor one-shot async loading. - Use
StreamProviderfor reactive streams. - Use
NotifierorAsyncNotifierfor feature state that needs mutation methods. - Use
autoDisposefor short-lived state. - Use
familywhen provider output depends on an argument. - Use
flutter_riverpodin Flutter apps. - If you use
flutter_riverpod, you usually do not addriverpodseparately because the Flutter package brings it in transitively. - Current stable line is Riverpod 3.x (
riverpod3.2.1,flutter_riverpod3.3.1).
Decision Guide
Choose Riverpod when:
- you want provider-based dependency injection and reactive state in one model
- state should be derived from other providers
- async data is a major part of the feature
- test overrides and scoped state matter
- you want fewer classes than a Bloc-heavy approach
Choose a different pattern when:
- the feature is a tiny local state toggle and a simple widget would be enough
- the logic is better expressed as an explicit event machine
Required Project Setup
For Dart-only code:
- add
riverpod
For Flutter UI code:
- add
flutter_riverpod - wrap the app in
ProviderScope - use
ConsumerWidget,Consumer, orConsumerStatefulWidgetwhererefis needed
If code generation is used:
- add
riverpod_annotation - add
riverpod_generator - add
build_runner
Implementation Pattern
Prefer this structure:
- providers own state, dependencies, and derived values
- repositories and APIs stay outside widgets
- UI reads state with
ref.watch - UI performs imperative reads with
ref.read - container-level overrides are used for tests, demos, and environment-specific wiring
Keep providers small and composable. Keep state immutable unless the provider type is specifically meant for mutation. Keep feature logic in providers or notifiers, not in widgets.
Lifecycle Rules
- Use
autoDisposefor short-lived screens and transient queries. - Use
ref.keepAlive()only when you want cached state to survive temporarily. - Prefer provider disposal over manual cleanup.
- In tests and pure Dart code, dispose
ProviderContainerwhen finished.
UI Binding Rules
Use ConsumerWidget when the whole widget depends on providers.
Use Consumer when only a small subtree needs access to ref.
Use ConsumerStatefulWidget when you need widget lifecycle plus ref.
Use select to reduce rebuilds.
Use ProviderListener or ref.listen for side effects.
Testing Rules
- Test providers through
ProviderContainer. - Override dependencies instead of mocking provider internals.
- Assert
AsyncValuestates directly for async providers. - Dispose containers in tests.
Common Pitfalls
- Do not call
ref.watchinside callbacks; useref.readthere. - Do not skip
ProviderScopeat the app root. - Do not use
StateProviderfor large feature state. - Do not put business logic in widgets.
- Do not rebuild the whole tree when a single field changes; use
select. - Do not model async loading manually when
FutureProviderorAsyncNotifierfits. - Do not forget provider overrides for tests and previews.
What To Prefer In Answers
When writing code or advising on design:
- show the smallest working provider first
- mention whether
ProviderScopeis required - mention whether the provider should be
autoDisposeor cached - mention whether a
familyis needed for arguments - include test override notes when dependencies are external
- keep examples aligned with the current Riverpod docs and Flutter integration patterns
- if code generation is involved, prefer matching
riverpod_annotation/riverpod_generatorversions from the same 3.x release line
Minimal Reference Checklist
ProviderScope= app root setupref.watch= rebuild on changeref.read= imperative accessselect= narrower rebuildsautoDispose= short-lived statefamily= parameterized providerProviderContainer= test/headless container