📢 Beta Documentation – This documentation and plugin are under active development. The plugin is live and ready to explore, but docs are in beta. Final release coming in May 2026. Please explore, test, and share feedback!

NotifierProvider

NotifierProvider replaces StateNotifierProvider in the newer Riverpod versions, managing complex class-based state synchronously.

A Notifier handles state logic synchronously. It's the recommended alternative to StateNotifier because it removes boilerplate, supports code generation out of the box, and provides direct access to ref.

When to Use Notifier

  • Managing complex, synchronous class-based state (e.g., a shopping cart or form inputs)
  • Replacing StateProvider with more constrained business logic
  • Encapsulating repetitive state manipulation methods

Basic Syntax

Define a Notifier and map its logic using the Riverpod Generator:

import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'cart.g.dart';

@riverpod
class Cart extends _$Cart {
  @override
  List<Product> build() {
    // Initial state is an empty cart
    return [];
  }

  void addProduct(Product product) {
    // State is immutable, so we create a new list
    state = [...state, product];
  }

  void removeProduct(String productId) {
    state = state.where((p) => p.id != productId).toList();
  }
}

Using Notifier in Widgets

To access the Notifier methods, use ref.read(provider.notifier):

class ShoppingCart extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final cart = ref.watch(cartProvider);

    return ListView.builder(
      itemCount: cart.length,
      itemBuilder: (context, index) {
        final product = cart[index];
        return ListTile(
          title: Text(product.name),
          trailing: IconButton(
            icon: Icon(Icons.delete),
            onPressed: () => ref.read(cartProvider.notifier).removeProduct(product.id),
          ),
        );
      },
    );
  }
}

⚠️ Important Rule

States in Riverpod are meant to be immutable. Never mutate an object or list directly (e.g., state.add(item)). Always assign a fresh object/collection (e.g., state = [...state, item]).