Riverpod: the async state is a value you match on, not an exception you catch
A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
At a glance
- What is it?
- Riverpod is a reactive caching and data-binding framework for Dart that grew out of Provider, and it publishes three packages: a framework-agnostic core plus Flutter and hooks variants. Its central move is that loading, data and error are one value you pattern match, so asynchronous work in a widget is a switch rather than a try and catch. The repository is a workspace with seven example apps and no release tags.
- Who is it for?
- Adopt it if you build Flutter or hooks-based Dart apps and want your data layer to be a plain function you can test without a widget tree. Before you start, pick the package that matches your app, since the framework-agnostic one exists for a reason, and read the contributing notes rather than the README for guidance on the current state of the project.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- rrousselGit/riverpod7,424 ★ · +38
| Repository | 2026-09-22 | 2026-11-13 |
|---|---|---|
| rrousselGit/riverpod | 7.4k | 7.4k |
38 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Three packages, and the one named riverpod is not the Flutter one
The README opens with a table that is really an installation decision. There are three published packages: riverpod, described with a link to its page on the language package server, then flutter_riverpod, and then hooks_riverpod. Only the first lacks a Flutter or hooks prefix. That split is the design in one line. The core package knows about caching and data binding and nothing about widgets, which is why the reference list at the bottom of the page links to the inherited widget API from the Flutter documentation and to the older state management package it grew out of, alongside the hooks package. The name itself is the joke that makes the lineage memorable: Riverpod is an anagram of Provider.
The generator is the centre, and the annotated function is the input
The long story short is two steps. First you define network requests by writing a function and annotating it:
@riverpod
Future<String> breweryName(Ref ref) async {
final response = await http.get(
Uri.https('api.openbrewerydb.org', '/v1/breweries/random'),
);
final json = jsonDecode(response.body) as List;
return (json.first as Map)['name']! as String;
}Then you watch the generated provider in your UI. So the unit you write and test is an ordinary asynchronous function that receives a ref and returns a value, with no widget and no context in sight. That is what makes the framework-agnostic package usable on its own, and it is also what makes the data layer testable without pumping a single frame.
Loading and error are branches of one value, and the wildcard branch is deliberate
The widget example is where the philosophy becomes concrete. You watch the provider and switch on the result:
final breweryName = ref.watch(breweryNameProvider);
// Perform a switch-case on the result to handle loading/error states
return switch (breweryName) {
AsyncData(:final value) => Text('data: $value'),
AsyncError(:final error) => Text('error: $error'),
_ => const Text('loading'),
};Three things are visible there. The states are variants of a single value rather than three separate mechanisms. The fallback is a wildcard rather than a named loading state, which keeps the code short at the cost of not distinguishing refreshing from first load. And the README states the behaviour in prose as handling errors and loading states by default with no need to manually catch errors, which is the sentence the design exists to justify.
Testable, scalable and reusable are claims about the data layer, not the widget
The four benefits listed near the top are worth separating because they are not the same kind of promise. Handling errors and loading states by default is a behaviour of the provider's value type. Natively supporting advanced scenarios, with pull-to-refresh named as the example, is about what the framework lets you express rather than about convenience. Separating logic from your UI is the architectural claim, and it is the one the generator supports directly, since a provider is produced from a function that knows nothing about the view. Testable, scalable and reusable follow from that separation, and they hold to the extent that you keep providers outside widgets. The README does not describe the refresh mechanism itself, so if pull-to-refresh is your reason to adopt, read the documentation site rather than the page.
Eight example apps, and two lint configurations that differ by plugins
The repository is a workspace rather than a package, and the top level shows how it is organised: a packages directory, an examples directory containing a counter, a first app, a marvel app, a pub example, a random number example, a stackoverflow example and a todos app, plus other projects, benchmarks, tools, scripts, a website and resources. Two configuration files at the root are the detail worth noticing. There is one analysis options file and another that is explicitly the same thing without plugins, alongside a file listing every lint rule and a development tools options file.
No release tags, and a push from the same day
Administratively the project is a pub package rather than a tagged release line. There are no GitHub releases at all, the repository is not archived, and the last push is dated 2026-11-01. The README itself points at the documentation site for learning, with the documentation link standing in the position where an install snippet would be. So if you are adopting this, your version comes from the package you depend on rather than from a tag you can pin. The contributing notes are short and specific, listing bug reports for difficult scenarios, unclear documentation, typos, documentation updates and examples, and new features through a pull request. That list is a fair description of what a project at this stage of its release process needs from outside.
Editorial conclusion
Adopt it if you build Flutter or hooks-based Dart apps and want your data layer to be a plain function you can test without a widget tree. Before you start, pick the package that matches your app, since the framework-agnostic one exists for a reason, and read the contributing notes rather than the README for guidance on the current state of the project.
Frequently asked questions
What is the Riverpod?
A reactive caching and data-binding framework for asynchronous code, and an anagram of Provider, the state management package it grew out of. It handles errors and loading states by default so you do not catch them manually, separates logic from the UI, and is built so code stays testable, scalable and reusable. Three packages are published: a framework-agnostic core plus Flutter and hooks variants.
how to install riverpod in flutter
Pick the package that matches your app. The framework-agnostic riverpod package is published on the language package server, and flutter_riverpod and hooks_riverpod are the application-facing ones. The README does not give an install command and instead points at the documentation site, which is where the setup instructions live.
what is riverpod used for
Defining asynchronous work such as network requests as annotated functions, then watching the generated provider in your UI and switching on the result to render data, an error or a loading state. The same approach applies to state and derived values, which is what keeps the data layer out of your widgets and testable without a widget tree.
what is riverpod generator
It is the annotation-based code generator. You write a function that receives a ref and mark it with @riverpod, and the generator produces the provider you then watch in the UI. The README's example is a network call returning a brewery name string, watched as a generated provider and matched against loading, data and error variants.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rrousselgit-riverpod)Star history chart for your README
[](https://hysenlabs.com/projects/rrousselgit-riverpod)Was this useful?