State Management Tradeoffs

State management is an architecture decision, not a package contest.

Comparison

ApproachBest forCostAgent fit
setStateLocal visual stateDoes not scale across screensGood when kept local
ValueNotifierSmall observable stateManual compositionGood for tiny starters
ChangeNotifierSimple view modelsMutable state can sprawlGood if APIs stay small
ProviderInherited access and DI around notifiersBuildContext coupling, package dependencyGood for simple apps with discipline
RiverpodExplicit providers, async state, test overridesNew concepts, provider graph decisionsStrong when app state grows
Bloc/CubitEvent/state discipline, auditabilityBoilerplate and ceremonyStrong for complex flows, weak for tiny apps

Recommendation

Use no default package in the stack pack. For actual app scaffolds:

  1. Start with local state and view models.
  2. If dependencies need clean overrides or async app state grows, use Riverpod.
  3. If workflows need explicit event logs and state transitions, use Bloc/Cubit.
  4. If the app is very small, ChangeNotifier/Provider can be enough.

Red Flags

  • One global app store for unrelated state.
  • State package added before a second screen exists.
  • View model methods that directly call platform channels.
  • Persistent data stored only in memory state.
  • Tests that pump a whole app to test simple state transitions.

Gotcha: State management packages do not fix unclear ownership. Decide who owns the data first: widget, screen, feature, repository, local database, or server.