# Riverpod

> Use when working with Flutter Riverpod state management. Covers providers, consumers, refs, containers, overrides, async state, code generation, testing, and safe defaults.

- Skill: `thedixitjain/riverpod` (Agent Skill)
- Install (CLI): `npx skillmds add thedixitjain/riverpod`
- Raw SKILL.md: https://api.skillmd.com/api/skills/thedixitjain/riverpod/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: thedixitjain (https://skillmd.com/u/thedixitjain)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/thedixitjain/riverpod

---



# Flutter Riverpod State Management

Use this skill when building Flutter state management with `riverpod` and `flutter_riverpod`.

## Core Rule

- Use `Provider` for read-only values and dependency wiring.
- Use `StateProvider` for small mutable state.
- Use `FutureProvider` for one-shot async loading.
- Use `StreamProvider` for reactive streams.
- Use `Notifier` or `AsyncNotifier` for feature state that needs mutation methods.
- Use `autoDispose` for short-lived state.
- Use `family` when provider output depends on an argument.
- Use `flutter_riverpod` in Flutter apps.
- If you use `flutter_riverpod`, you usually do not add `riverpod` separately because the Flutter package brings it in transitively.
- Current stable line is Riverpod 3.x (`riverpod` 3.2.1, `flutter_riverpod` 3.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`, or `ConsumerStatefulWidget` where `ref` is 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 `autoDispose` for 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 `ProviderContainer` when 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 `AsyncValue` states directly for async providers.
- Dispose containers in tests.

## Common Pitfalls

- Do not call `ref.watch` inside callbacks; use `ref.read` there.
- Do not skip `ProviderScope` at the app root.
- Do not use `StateProvider` for 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 `FutureProvider` or `AsyncNotifier` fits.
- 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 `ProviderScope` is required
- mention whether the provider should be `autoDispose` or cached
- mention whether a `family` is 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_generator` versions from the same 3.x release line

## Minimal Reference Checklist

- `ProviderScope` = app root setup
- `ref.watch` = rebuild on change
- `ref.read` = imperative access
- `select` = narrower rebuilds
- `autoDispose` = short-lived state
- `family` = parameterized provider
- `ProviderContainer` = test/headless container

---

**Source:** [`andrewyng/context-hub`](https://github.com/andrewyng/context-hub) → `content/flutter/skills/state-management/riverpod/SKILL.md`

