riverpod-containers
Riverpod — Containers / Scopes
Instructions
Providers themselves hold no state. State is stored in a ProviderContainer. In Flutter you use the ProviderScope widget, which creates and exposes a container to the widget tree.
Flutter: ProviderScope
Wrap your app at the root so widgets can read providers:
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
After that, use Consumer / ConsumerWidget / ConsumerStatefulWidget to get a ref and call ref.watch / ref.read. You can also pass overrides or observers to ProviderScope.
Pure Dart: ProviderContainer
In command-line or server-side Dart, create a container, use it, then dispose it:
void main() {
final container = ProviderContainer();
try {
final sub = container.listen(counterProvider, (previous, next) {
print('Counter changed from $previous to $next');
});
print('Counter starts at ${sub.read()}');
} finally {
container.dispose();
}
}
Why state lives in a container
- Separation of concerns — Only the provider (and ref) can change its state; the UI typically calls notifier methods.
- Testing — Each test can create a new container (e.g.
ProviderContainer.test()) for a fresh state; no shared global state. - Configuration — Overrides and observers are set on the container/scope. See riverpod-overrides and riverpod-observers.
- Scoping — The same provider can resolve to different state in different parts of the tree (advanced). See riverpod-scoping.
Testing
Do not use ProviderContainer() directly in tests. Use ProviderContainer.test() so the container is disposed when the test ends:
test('Counter starts at 0 and can be incremented', () {
final container = ProviderContainer.test();
expect(container.read(counterProvider), 0);
container.read(counterProvider.notifier).increment();
expect(container.read(counterProvider), 1);
});
In widget tests, wrap the widget in ProviderScope and use tester.container() to get the container if needed (see riverpod-testing).
More from serverpod/skills-registry
riverpod-codegen-and-hooks
Use Riverpod code generation (@riverpod, riverpod_generator) and hooks (hooks_riverpod, HookConsumerWidget, flutter_hooks with Riverpod). Use when the user asks about @riverpod, code generation, riverpod_generator, when to use codegen, or using flutter_hooks with Riverpod (HookConsumerWidget, HookConsumer).
25riverpod-providers
Declare and use Riverpod providers (Provider, FutureProvider, StreamProvider, NotifierProvider, AsyncNotifierProvider, StreamNotifierProvider); unmodifiable vs modifiable, top-level declaration, Ref, Notifier build method. Use when creating providers, choosing provider type, writing Notifier classes, or understanding Riverpod state. Use this skill whenever the user asks about Riverpod providers, provider types, or notifiers.
24riverpod-consumers
Use Riverpod Consumer, ConsumerWidget, and ConsumerStatefulWidget to read and watch providers in widgets; WidgetRef, builder ref parameter. Use when building widgets that need to access Riverpod providers, ref.watch or ref.read in the UI, or converting StatelessWidget to ConsumerWidget. Prefer this skill when the user asks how to use providers in Flutter widgets or why ConsumerWidget is required.
19riverpod-getting-started
Install Riverpod (flutter_riverpod or riverpod), wrap the app in ProviderScope, run a hello-world provider, and optionally enable riverpod_lint and code generation. Use when starting a Flutter or Dart project with Riverpod, adding the Riverpod dependency, or setting up ProviderScope and a first provider. For version highlights see the official Riverpod docs.
18riverpod-auto-dispose
Enable automatic disposal of Riverpod providers when they have no listeners; keepAlive, onDispose, invalidate, ref.keepAlive. Use when preventing memory leaks, caching only while used, or cleaning up resources when a provider is no longer needed. Use this skill when the user asks about auto-dispose, keepAlive, or when to dispose Riverpod state.
17riverpod-refs
Use Ref and WidgetRef to read, watch, listen, invalidate, and refresh providers; onDispose and onCancel lifecycle; ref.read vs ref.watch vs ref.listen, ref.invalidate and ref.refresh. Use when interacting with Riverpod providers from widgets or other providers, when to use watch vs read, or when resetting provider state. Use this skill whenever the user asks about ref.watch, ref.read, ref.listen, ref.invalidate, or Riverpod lifecycle.
16