Declarative programming
Write business logic in a manner similar to Stateless widgets.
Have your
network requests to automatically recompute when necessary and make
your logic easily reusable/composable/maintainable.
Easily implement common UI patterns
Using Riverpod, common yet complex UI patterns such as "pull to refresh"/ "search as we type"/etc... are only a few lines of code away.
Tooling ready
Riverpod enhances the compiler by having common mistakes be a compilation-error. It also provides custom lint rules and refactoring options. It even has a command line for generating docs.
Features
Everything you need to build robust, scalable, and maintainable Dart & Flutter applications.
Declare shared state from anywhere
No need to jump between your main.dart and your UI files
anymore.
Place the code of your shared state where it belongs, be
it in a separate package or right next to the Widget that
needs it, without losing testability.
// A shared state that can be accessed by multiple widgets at the same time.
class Count extends _$Count {
int build() => 0;
void increment() => state++;
}
// Consumes the shared state and rebuild when it changes
class Title extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('$count');
}
}
Recompute states/rebuild UI only when needed
We no longer have to sort/filter lists inside the build
method or have to resort to advanced cache mechanism.
With Provider and "families", sort your lists or do HTTP
requests only when you truly need it.
List<Todo> filteredTodos(Ref ref) {
// Providers can consume other providers using the "ref" object.
// With ref.watch, providers will automatically update if the watched values changes.
final List<Todo> todos = ref.watch(todosProvider);
final Filter filter = ref.watch(filterProvider);
switch (filter) {
case Filter.all:
return todos;
case Filter.completed:
return todos.where((todo) => todo.completed).toList();
case Filter.uncompleted:
return todos.where((todo) => !todo.completed).toList();
}
}
Inspect your state with the Flutter DevTools extension
Riverpod includes a dedicated Flutter DevTools extension that allows inspecting the state of all your providers.
It even allows going back in time to inspect older states.

Simplify day-to-day work with refactors
Riverpod offers various refactors, such as "Wrap widget in a Consumer" and many more. See the list of refactorings.

Keep your code maintainable with lint rules
New lint-rules specific to Riverpod are implemented and more are continuously added. This ensures your code stays in the best conditions. See the list of lint rules.

Safely read providers
Reading a provider will never result in a bad state. If you
can write the code needed to read a provider, you will obtain
a valid value.
This even applies to asynchronously loaded values. As opposed
to with provider, Riverpod allows cleanly handling
loading/error cases.
Future<Configuration> configurations(Ref ref) async {
final uri = Uri.parse('configs.json');
final rawJson = await File.fromUri(uri).readAsString();
return Configuration.fromJson(json.decode(rawJson));
}
class Example extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final configs = ref.watch(configurationsProvider);
// Use pattern matching to safely handle loading/error states
return switch (configs) {
AsyncData(:final value) => Text('data: ${value.host}'),
AsyncError(:final error) => Text('error: $error'),
_ => const CircularProgressIndicator(),
};
}
}
Sponsors
Riverpod is open source software funded by the community and our generous sponsors.