Skip to content

Migrate from Riverpod 2.x to Riverpod 3.x #512

@mostronatorcoder

Description

@mostronatorcoder

Why This Is Needed

As of Flutter 3.29+ (stable channel, March 2026), riverpod_generator 2.6.5 is incompatible with the Flutter SDK:

Because riverpod_generator 2.6.5 depends on analyzer ^7.0.0
And test >=1.29.0 depends on analyzer >=8.0.0 <11.0.0
→ version solving failed

Flutter's test package now requires analyzer >=8.0.0, but riverpod_generator 2.x is pinned to analyzer ^7.0.0. This means we cannot update Flutter without migrating Riverpod.

Current versions in pubspec.yaml:

  • flutter_riverpod: ^2.6.1
  • hooks_riverpod: ^2.6.1
  • riverpod_annotation: ^2.6.1
  • riverpod_generator: ^2.6.5
  • build_runner: ^2.4.0

Target versions:

  • flutter_riverpod: ^3.0.0
  • hooks_riverpod: ^3.0.0
  • riverpod_annotation: ^4.0.0
  • riverpod_generator: ^3.0.0
  • build_runner: ^2.4.0 (unchanged)

Impact Assessment

Good news: only 3 files use @riverpod code generation:

  • lib/services/event_bus.dart
  • lib/shared/providers/mostro_service_provider.dart
  • lib/features/order/providers/order_notifier_provider.dart

The other ~83 provider/notifier files use manual provider declarations (StateNotifierProvider, FutureProvider, NotifierProvider, etc.), which have minimal breaking changes in 3.x.

Breaking Changes in Riverpod 3.x

Must Fix (Breaking)

  1. Generated Ref subclasses are removed — Change FooRef refRef ref in all @riverpod annotated functions
  2. Family arguments no longer on Ref — Override methods now receive args as a separate parameter
  3. ChangeNotifierProvider removed — Must migrate to NotifierProvider (verify we don't use this)
  4. Provider lifecycle changesautoDispose behavior tweaks; providers may dispose earlier than in 2.x
  5. AsyncValue.copyWithPrevious is now @internal — Cannot be used in app code

Nice to Have (New Features)

  • Offline persistence (experimental) — persist() method on notifiers
  • Mutations (experimental) — @mutation annotation for side-effects
  • Automatic retry — Providers retry on failure with exponential backoff
  • Ref.mounted — Check if provider is still alive (like BuildContext.mounted)
  • Generic providers — Code-generated providers can have type parameters
  • ProviderContainer.test — Simplified testing utilities

Migration Plan

Phase 1: Preparation (low risk)

  • Audit all 3 @riverpod files for breaking patterns
  • Audit manual providers for ChangeNotifierProvider usage (should be zero)
  • Check for AsyncValue.copyWithPrevious usage
  • Check for custom Ref subclass usage (FooRef)
  • Document current test coverage baseline

Phase 2: Bump Dependencies (single PR)

  • Update pubspec.yaml to Riverpod 3.x versions
  • Fix the 3 @riverpod annotated files:
    • Replace FooRef refRef ref
    • Update family argument patterns if needed
  • Run dart run build_runner build --delete-conflicting-outputs
  • Fix any compilation errors in manual providers
  • Run flutter analyze — fix all issues
  • Run flutter test — fix broken tests

Phase 3: Verify (same PR or follow-up)

  • Test on Android (build APK)
  • Test on Linux desktop
  • Smoke test core flows: create order, take order, chat, disputes
  • Verify no provider lifecycle regressions (providers disposing too early)

Phase 4: Optional Improvements (future PRs)

  • Adopt Ref.mounted where we have async gaps
  • Evaluate @mutation for form submissions
  • Evaluate offline persistence for order cache
  • Clean up any deprecated patterns

Risk Assessment

Low-Medium risk because:

  • Only 3 files use code generation (the main source of breaking changes)
  • ~83 manual provider files need minimal changes (mostly API-compatible)
  • Lifecycle changes are subtle but could cause hard-to-debug issues
  • Good test coverage reduces regression risk

Workaround

Until this migration is done, pin Flutter to 3.27.x (the last version compatible with riverpod_generator 2.x):

# In pubspec.yaml
environment:
  sdk: ">=3.5.0 <4.0.0"
  flutter: ">=3.27.0 <3.29.0"

Or simply don't update Flutter on dev machines.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions