← Open Source
package · v0.4.25

utopia_hooks

Flexible state management for Flutter, inspired by React Hooks.

dependencies:
  utopia_hooks: ^0.4.25
flutter pub add utopia_hooks
why it exists
A Flutter screen has to do four things: hold local state, read shared app state, run async work, and stay testable. The framework gives you one tool for the first job - StatefulWidget - 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.
usage
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++,
    );
  }
}
talk to us

Want this in your build?

The team behind utopia_hooks ships production Flutter on the same stack. Tell us what you are building.