Write flow stays explicit.

Define mutations as provider methods, monitor state with MutationToken, and execute each call through ref.invoke(call).

Mutation Building Blocks

A mutation is a Call<R, State> returned from mutate(token, body, concurrency: ...).

Token

late final renameMut = mutation<void>(#rename)

Execution

await ref.invoke(provider.rename(...))

State

Idle / Pending / Success / Error via ref.watch(token)

Note

Unlike notifier.method() style APIs, miniriverpod makes mutation execution a first-class call object.

Execute a mutation

Choose ref.invoke so cancellation and drop behavior are visible to the caller. The workflow remains easy to review.

Run

Concurrency options

concurrent : run all calls in parallel (default).
queue      : FIFO; keep running queued calls even after an error.
restart    : cancel previous run, keep only latest call.
dropLatest : drop incoming calls while one is running.

Example: optimistic update with restart

A common write pattern updates AsyncData optimistically, then syncs with server response.

class UserProvider extends AsyncProvider<User?> {
  UserProvider() : super.args(null);

  late final renameMut = mutation<void>(#rename);

  Call<void, AsyncValue<User?>> rename(String newName) => mutate(
    renameMut,
    (ref) async {
      final cur = ref.watch(this).valueOrNull;
      ref.state = AsyncData((cur ?? const User()).copyWith(name: newName), isRefreshing: true);

      final api = ref.watch(apiProvider);
      await api.rename(newName);
      ref.state = AsyncData(await api.me());
    },
    concurrency: Concurrency.restart,
  );
}
restart may throw CancelledMutation to older callers.
dropLatest may throw DroppedMutation while busy.
Catch these in UI when you want to suppress transient cancellation errors.

Next Steps

Flutter API

Bind mutation state to UI using ConsumerWidget or ConsumerStatefulWidget.

Open Flutter API

API Reference

Review invoke, mutation, mutate, and MutationState types quickly.

Open API Reference