Skip to main content


ProviderObserver listens to the changes of a ProviderContainer.

To use it, extend the class ProviderObserver and override the method you want to use.

ProviderObserver has three methods :

  • didAddProvider is called every time a provider was initialized, and the value exposed is value.
  • didDisposeProvider is called every time a provider was disposed.
  • didUpdateProvider is called every time by providers when they emit a notification.

Usage :

A simple use case for ProviderObserver is to log the changes in providers by overriding the didUpdateProvider method.

// A Counter example implemented with riverpod with Logger

class Logger extends ProviderObserver {

void didUpdateProvider(
ProviderBase<Object?> provider,
Object? previousValue,
Object? newValue,
ProviderContainer container,
) {
"provider": "${ ?? provider.runtimeType}",
"newValue": "$newValue"

void main() {
// Adding ProviderScope enables Riverpod for the entire project
// Adding our Logger to the list of observers
ProviderScope(observers: [Logger()], child: const MyApp()),

class MyApp extends StatelessWidget {
const MyApp({super.key});

Widget build(BuildContext context) {
return MaterialApp(home: Home());

final counterProvider = StateProvider((ref) => 0, name: 'counter');

class Home extends ConsumerWidget {

Widget build(BuildContext context, WidgetRef ref) {
final count =;

return Scaffold(
appBar: AppBar(title: const Text('Counter example')),
body: Center(
child: Text('$count'),
floatingActionButton: FloatingActionButton(
onPressed: () =>,
child: const Icon(Icons.add),

Now, every time the value of our provider is updated, the logger will log it:

I/flutter (16783): {
I/flutter (16783): "provider": "counter",
I/flutter (16783): "newValue": "1"
I/flutter (16783): }

For states that are mutable such as StateController (the state of StateProvider.state) and ChangeNotifier the previousValue and newValue will be the same

since they reference the same StateController / ChangeNotifier.