utopia_hooks
Flexible state management for Flutter, inspired by React Hooks.
dependencies:
utopia_hooks: ^0.4.25flutter pub add utopia_hooksStatefulWidget - and leaves the rest to a patchwork of libraries. utopia_hooks is one model for all four: a counter in BLoC is three files and five classes; the same behavior here is one hook and one function.The model is decoupled from the widget tree by construction. utopia_hooks shares its vocabulary with flutter_hooks, but it is not a fork or a superset - it is a separate implementation that puts an abstraction layer,
HookContext, between hooks and Flutter, and HookWidget is only one implementation of that context. That is why hook state stays background-safe and unit-testable in plain Dart: SimpleHookContext drives the same state in a test with no widget harness at all.It is the state layer behind every app we ship - the same model stretches to pagination and forms - so you reach for one idiom instead of a different package per problem. Screen · State · View is the architecture pattern utopia_hooks implements: a Screen composes the hooks, a hook-based State holds the logic decoupled from the widget tree, and a View renders it. That same Screen/State/View discipline is also a published Claude Code skill - the structure our agents follow when they write a hook-based screen - and the docs make the case for hooks as a state layer an agent can read and verify.
Habicy runs on it in production - eighteen global-state hooks behind a live social app on iOS and Android. See how the stack holds up outside a demo.
The hook catalog
HookWidgetA StatefulWidget you call hooks inside - the entry point for the pattern, with no hand-written State class.
useStateA single mutable value that rebuilds on change. The primitive everything else composes from.
useEffectRun a side effect in response to changes, with a dispose callback for cleanup.
useProvidedRead app-wide state registered higher up in a HookProviderContainerWidget, and rebuild when it changes.
useComputedStateDerived state, including async - values that recompute when their inputs change.
useSubmitStateSubmission and async-action state (loading / error / done) without the boilerplate.
usePaginatedComputedStateCursor-based pagination and infinite scroll as a single hook.
class CounterButton extends HookWidget {
@override
Widget build(BuildContext context) {
final counter = useState(0);
useEffect(() {
print('Counter changed to ${counter.value}');
}, [counter.value]);
return ElevatedButton(
child: Text('Counter: ${counter.value}'),
onPressed: () => counter.value++,
);
}
}Want this in your build?
The team behind utopia_hooks ships production Flutter on the same stack. Tell us what you are building.


