mcpField
R
riverpod-containers

riverpod-containers

github.com/serverpodDevelopment1073 installsUpdated 34w ago
Repository

About riverpod-containers

A Riverpod skill explaining how ProviderContainer and ProviderScope hold provider state across Flutter apps, Dart code, and tests. It covers state isolation, configuration, and scoped overrides.

Key features

  1. 01ProviderScope setup in Flutter
  2. 02ProviderContainer use in Dart
  3. 03Fresh containers for tests
  4. 04Overrides and observers
  5. 05Provider scoping guidance

Use cases

  1. 01Set up Riverpod state in a Flutter app
  2. 02Manage providers in command-line or server-side Dart
  3. 03Isolate state across tests
  4. 04Apply provider overrides to a subtree

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/serverpod/skills-registry --skill riverpod-containers

After installing, type/riverpod-containersin Claude Code to confirm it loaded.

Details

From the project README

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).

Comments

Markdown supported