Expert knowledge in Flutter Riverpod state management (2025 best practices). Use when working with Riverpod, Flutter state management, AsyncNotifier, provider types, code generation with riverpod_generator, state synchronization, or when the user mentions data fetching, mutations, reactive state, performance optimization, or testing in Flutter apps. Covers AsyncNotifierProvider patterns, repository architecture, autoDispose, family providers, and common anti-patterns to avoid.
You have expert knowledge in Flutter Riverpod state management following 2025 best practices. When the user is working with Riverpod or Flutter state management, apply these patterns and guidelines.
Activate this expertise when the user mentions:
@riverpod annotations and riverpod_generatorselect() to optimize rebuildsImmutable/Computed Values - Use Provider:
@riverpod
String apiKey(Ref ref) => 'YOUR_API_KEY';
@riverpod
int totalPrice(Ref ref) {
final cart = ref.watch(cartProvider);
return cart.items.fold(0, (sum, item) => sum + item.price);
}
Simple Synchronous State - Use NotifierProvider:
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
void decrement() => state = max(0, state - 1);
}
Async Data with Mutations (PREFERRED 2025) - Use AsyncNotifierProvider:
@riverpod
class TodoList extends _$TodoList {
@override
Future<List<Todo>> build() async {
final repo = ref.watch(todoRepositoryProvider);
return repo.fetchTodos();
}
Future<void> addTodo(String title) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() async {
final repo = ref.read(todoRepositoryProvider);
await repo.createTodo(title);
return repo.fetchTodos();
});
}
Future<void> deleteTodo(String id) async {
// Optimistic update
state = AsyncData(state.value!.where((t) => t.id != id).toList());
try {
await ref.read(todoRepositoryProvider).deleteTodo(id);
} catch (e) {
ref.invalidateSelf(); // Rollback on error
}
}
}
Real-time Streams Only - Use StreamProvider:
@riverpod
Stream<User?> authState(Ref ref) {
return FirebaseAuth.instance.authStateChanges();
}
Key Rule: Prefer AsyncNotifierProvider over FutureProvider/StreamProvider for better consistency and mutation support.