Home › Flutter › Flutter + Riverpod rules
Flutter + Riverpod rules
Cursor rules for Flutter 3 apps using Riverpod 3 with code generation, go_router, and widget tests.
CursorFlutter
How to use
Save this as .cursor/rules/flutter-riverpod.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
.cursor/rules/flutter-riverpod.mdcDownload ---
description: Flutter + Riverpod conventions
globs: ["lib/**/*.dart","test/**/*.dart"]
alwaysApply: false
---
# Flutter + Riverpod
- Providers use code generation: annotate with `@riverpod`, run `dart run build_runner watch -d`. Don't hand-write `StateNotifierProvider` (legacy).
- Async state: `@riverpod Future<T>` / class-based `AsyncNotifier`. Render with `ref.watch(provider).when(data:, loading:, error:)` or pattern matching on `AsyncValue`.
- `ref.watch` in build, `ref.read` in callbacks, `ref.listen` for side effects like snackbars and navigation.
- Widgets are `ConsumerWidget`/`ConsumerStatefulWidget` only when they read providers; keep leaf widgets plain `StatelessWidget` with `const` constructors.
- Repositories are providers too, so tests can override them with `ProviderScope(overrides: [...])` / `ProviderContainer`.
- Routing with `go_router`; redirects based on an auth provider.
- Models immutable (`freezed` or plain `final` fields with `copyWith`). JSON via `json_serializable`.
- Split widgets into small classes instead of helper methods returning widgets.
- Theme via `ThemeData`/`ColorScheme.fromSeed`; no hard-coded colors in widgets.
## Don't
- Don't keep business logic in widgets, or call `setState` for shared state.
- Don't commit edits to `*.g.dart` / `*.freezed.dart` by hand.
## Done when
`dart format --set-exit-if-changed .`, `flutter analyze` and `flutter test` pass.