accessibility
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when setting up providers, combining requests, managing state disposal, passing arguments, performing side effects, or testing providers (Riverpod).
Claude Code
$ npx -y skills add evanca/flutter-ai-rules --skill riverpod --agent claude-code
Codex
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a codex -y
Cursor
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a cursor -y
Gemini CLI
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a gemini-cli -y
GitHub Copilot
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a github-copilot -y
OpenCode
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a opencode -y
Windsurf
$ npx skills add evanca/flutter-ai-rules --skill riverpod -a windsurf -y
name: riverpod description: "Use when setting up providers, combining requests, managing state disposal, passing arguments, performing side effects, or testing providers (Riverpod)." license: MIT
This skill defines how to correctly use Riverpod for state management in Flutter and Dart applications.
---
void main() {
runApp(const ProviderScope(child: MyApp()));
}---
// Functional provider (codegen)
@riverpod
int example(Ref ref) => 0;
// FutureProvider (codegen)
@riverpod
Future<List<Todo>> todos(Ref ref) async {
return ref.watch(repositoryProvider).fetchTodos();
}
// Notifier (codegen)
@riverpod
class TodosNotifier extends _$TodosNotifier {
@override
Future<List<Todo>> build() async {
return ref.watch(repositoryProvider).fetchTodos();
}
Future<void> addTodo(Todo todo) async { ... }
}---
| Method | Use for | |---|---| | `ref.watch` | Reactively listen — rebuilds when value changes. Use during build phase only. | | `ref.read` | One-time access — use in callbacks/Notifier methods, not in build. | | `ref.listen` | Imperative subscription — prefer `ref.watch` where possible. | | `ref.onDispose` | Cleanup when provider state is destroyed. |
// In a widget
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final value = ref.watch(myProvider);
return Text('$value');
}
}
// Cleanup in a provider
final provider = StreamProvider<int>((ref) {
final controller = StreamController<int>();
ref.onDispose(controller.close);
return controller.stream;
});---
@riverpod
Future<String> userGreeting(Ref ref) async {
final user = await ref.watch(userProvider.future);
return 'Hello, ${user.name}!';
}---
@riverpod
Future<Todo> todo(Ref ref, String id) async {
return ref.watch(repositoryProvider).fetchTodo(id);
}
// Usage
final todo = ref.watch(todoProvider('some-id'));---
// keepAlive with timer
ref.onCancel(() {
final link = ref.keepAlive();
Timer(const Duration(minutes: 5), link.close);
});---
Providers are **lazy** by default. To eagerly initialize:
// In MyApp or a dedicated widget under ProviderScope:
Consumer(
builder: (context, ref, _) {
ref.watch(myEagerProvider); // forces initialization
return const MyApp();
},
)---
@riverpod
class TodosNotifier extends _$TodosNotifier {
Future<void> addTodo(Todo todo) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() async {
await ref.read(repositoryProvider).addTodo(todo);
return [...?state.value, todo];
});
}
}
// In UI:
ElevatedButton(
onPressed: () => ref.read(todosNotifierProvider.notifier).addTodo(todo),
child: const Text('Add'),
)---
class MyObserver extends ProviderObserver {
@override
void didUpdateProvider(ProviderObserverContext context, Object? previousValue, Object? newValue) {
print('[${context.provider}] updated: $previousValue → $newValue');
}
@override
void providerDidFail(ProviderObserverContext context, Object error, StackTrace stackTrace) {
// Report to error service
}
}
runApp(ProviderScope(observers: [MyObserver()], child: MyApp()));---
// Unit test final container = ProviderContainer( overrides: [reposit
36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when creating a feature, designing folder structure, adding repositories/services/view models, wiring dependency injection,…
Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring…
Use when asked to review a PR, MR, branch, or diff, audit changed files, or check code quality.
Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring…
Use when building AI agents in Dart, implementing Genkit flows or tools, integrating LLMs into Dart or Flutter applications, or…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.