skills/flutter-state-management/SKILL.md
Riverpod state management patterns for Flutter: providers, notifiers, async state, and clean architecture integration. Trigger: When creating Riverpod providers, managing async state, or connecting UI to business logic in the mobile app.
npx skillsauth add 333-333-333/agents flutter-state-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
What kind of state do you need?
Computed value from other providers? → Provider (read-only)
Simple sync state with mutations? → NotifierProvider
Async data (API, DB) with mutations? → AsyncNotifierProvider
Async data (read-only, auto-fetch)? → FutureProvider
Real-time stream (WebSocket, Firestore)? → StreamProvider
For derived/computed values. No mutations.
Example: See assets/provider_read_only.dart
For local, synchronous state that needs to be mutated.
Example: See assets/notifier_sync.dart
For data that comes from an API/DB and can be mutated. Uses AsyncValue.guard() for safe state transitions.
Example: See assets/async_notifier_crud.dart
For async data you only need to FETCH, not mutate. Supports .family for parameterized queries.
Example: See assets/future_provider.dart
For Firestore listeners, WebSocket streams, etc.
Example: See assets/stream_provider.dart
Every async provider returns AsyncValue<T>. ALWAYS handle all 3 states: loading, error, data. Two approaches: .when() method or Dart 3.0 pattern matching.
Example: See assets/async_value_consumer.dart
Page (ConsumerWidget)
→ watches provider
→ provider uses use case
→ use case calls repository interface (domain)
→ repository impl (infrastructure) calls API
Repository providers and use case providers connect clean architecture layers via Riverpod's Provider.
Example: See assets/di_wiring.dart
| Scenario | Use |
|----------|-----|
| Screen-level data (detail pages) | autoDispose — clean up when leaving |
| Global state (auth, user session) | Keep alive (no autoDispose) |
| Lists that are expensive to re-fetch | Keep alive or cache manually |
| Form state | autoDispose — reset on navigation |
Example: See assets/auto_dispose.dart
| Element | Pattern | Example |
|---------|---------|---------|
| Read-only provider | {thing}Provider | currentUserProvider |
| Notifier class | {Thing}Notifier | BookingFilterNotifier |
| NotifierProvider | {thing}Provider | bookingFilterProvider |
| AsyncNotifier class | {Thing}Notifier | PetListNotifier |
| FutureProvider | {thing}Provider | caregiverDetailProvider |
| StreamProvider | {thing}Provider | chatMessagesProvider |
| Repository provider | {feature}RepositoryProvider | authRepositoryProvider |
| Use case provider | {useCase}Provider | loginUseCaseProvider |
| ❌ Don't | ✅ Do |
|----------|-------|
| ref.read in build() method | Use ref.watch to rebuild on changes |
| Business logic inside the widget | Put logic in Notifier or UseCase |
| Ignore loading/error states | Always handle all 3 AsyncValue states |
| One giant provider file for everything | One provider file per feature |
| Call API directly from provider | Provider → UseCase → Repository |
| Forget autoDispose on detail pages | Use autoDispose for screen-scoped data |
testing
Review Flutter components and screens for UX/UI compliance. Trigger: When user invokes /ux-review command or requests UX audit.
development
TypeScript strict patterns and best practices. Trigger: When implementing or refactoring TypeScript in .ts/.tsx (types, interfaces, generics, const maps, type guards, removing any, tightening unknown).
testing
Testing philosophy and strategy for every feature: test pyramid, mandatory levels per change type, completion checklist, and skill delegation. Trigger: When planning tests for a feature, reviewing test coverage, defining acceptance criteria, or asking what tests a change needs.
development
Terraform security practices: sensitive variables, secret management, state protection, .gitignore patterns, and CI/CD credential handling. Trigger: When handling secrets in Terraform, configuring state backends, reviewing .gitignore for Terraform, or setting up CI/CD pipelines for infrastructure.