watch_it 2.4.1 copy "watch_it: ^2.4.1" to clipboard
watch_it: ^2.4.1 copied to clipboard

The simple state management powered by get_it. It allows to observe changes of objects inside the get_it service locator and rebuild the UI accordingly.

watch_it logo
Buy Me A Coffee
Sponsor

watch_it codecov #

πŸ“š Complete documentation available at flutter-it.dev Check out the comprehensive docs with detailed guides, examples, and best practices!

The easiest state management for Flutter built on get_it

Widgets automatically rebuild when data changes. No ValueListenableBuilder, no StreamBuilder, no FutureBuilderβ€”just watch your data and your UI stays in sync.

One line instead of 12. No nesting, no boilerplate. Watch multiple values without builder hell.

Part of flutter_it β€” A construction set of independent packages. watch_it + get_it is the recommended foundation. Add command_it and listen_it when you need them.

Why watch_it? #

  • ✨ Zero Boilerplate β€” No Builders, no setState, no widget tree nesting
  • ⚑ Automatic Cleanup β€” Subscriptions disposed automatically when widget destroys
  • 🎯 Type Safe β€” Catch errors at compile time with generics
  • πŸ”§ Flexible Data Types β€” Works with Listenable, ValueListenable, Stream, Future
  • πŸ“Š Multiple Watches β€” Watch 3+ values without pyramid of doom
  • πŸ§ͺ Test Friendly β€” Easy to mock and inject dependencies

Learn more about the benefits β†’

Quick Start #

Installation #

Add to your pubspec.yaml:

dependencies:
  watch_it: ^2.2.0
  get_it: ^9.0.5  # Recommended - watch_it builds on get_it

Basic Example #

import 'package:watch_it/watch_it.dart';

// 1. Create a model with ValueNotifier properties
class CounterModel {
  final count = ValueNotifier<int>(0);
  void increment() => count.value++;
}

// 2. Register with get_it (using exported 'di' instance)
di.registerSingleton(CounterModel());

// 3. Watch it - widget rebuilds automatically
class CounterWidget extends WatchingWidget {
  @override
  Widget build(BuildContext context) {
    final count = watchValue((CounterModel m) => m.count);
    return Column(
      children: [
        Text('$count'),
        ElevatedButton(
          onPressed: di<CounterModel>().increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

That's it! No builders, no manual subscriptions. Just watch and rebuild.

Multiple Watches #

Watch multiple values without nesting builders:

class UserDashboard extends WatchingWidget {
  @override
  Widget build(BuildContext context) {
    // Watch multiple values - no nested builders!
    final userName = watchValue((UserModel m) => m.name);
    final isLoggedIn = watchValue((AuthModel m) => m.isLoggedIn);
    final notifications = watchStream(
      (NotificationModel m) => m.updates,
      initialValue: []
    );

    if (!isLoggedIn) return LoginScreen();

    return Text(
      '$userName - ${notifications.data?.length ?? 0} notifications'
    );
  }
}

Full tutorial

Key Features #

Watch Functions #

Replace Builders with simple one-line watch calls:

  • watchValue β€” Watch ValueListenable properties from get_it objects

  • watchIt β€” Watch whole Listenable objects registered in get_it

  • watchPropertyValue β€” Watch specific property, rebuilds only when value changes

  • watchStream β€” Reactive streams without StreamBuilder

  • watchFuture β€” Reactive futures without FutureBuilder

  • watch β€” Watch any local Listenable

Handler Functions (Side Effects) #

Execute side effects without rebuilding:

Lifecycle Helpers #

Powerful functions for StatelessWidgets:

  • createOnce β€” Create objects on first build, auto-dispose on widget destroy

  • callOnce β€” Execute function only on first build

  • callOnceAfterThisBuild β€” Execute function once after current build completes

  • callAfterEveryBuild β€” Execute function after every rebuild

  • pushScope β€” Automatic get_it scope management tied to widget lifecycle

Important Rules ⚠️ #

All watch* calls must:

  • Be called inside build() method
  • Be called in same order every build
  • Not be conditional (no if wrapping watch calls)

Why these rules? watch_it uses index-based retrieval similar to React Hooks. Changing the order breaks the mapping between calls and stored data.

Read the detailed explanation β†’

Widget Types #

Choose the widget type that fits your needs:

  • WatchingWidget β€” Extends StatelessWidget, use for simple widgets
  • WatchingStatefulWidget β€” Extends StatefulWidget, use when you need lifecycle or local state
  • WatchItMixin β€” Add to existing StatelessWidget with with WatchItMixin
  • WatchItStatefulWidgetMixin β€” Add to existing StatefulWidget with with WatchItStatefulWidgetMixin

Learn which to use when β†’

Ecosystem Integration #

Built on get_it β€” watch_it is designed to work with get_it's service locator pattern. Register your models, services, and business logic with get_it, then watch them reactively.

// Register with get_it
di.registerLazySingleton(() => UserManager());
di.registerLazySingleton(() => TodoManager());

// Watch them in any widget
class MyWidget extends WatchingWidget {
  @override
  Widget build(BuildContext context) {
    final user = watchIt<UserManager>();
    final todos = watchValue((TodoManager m) => m.todos);
    return ListView(...);
  }
}

Want more? Combine with other flutter_it packages:

  • get_it β€” Recommended pairing. Service locator for dependency injection. Access global services with di<T>().

  • Optional: command_it β€” Command pattern with loading/error states. Watch Commands reactively for automatic UI updates.

  • Optional: listen_it β€” ValueListenable operators (map, debounce, where). Watch reactive collections (ListNotifier, MapNotifier, SetNotifier).

πŸ’‘ flutter_it is a construction set β€” watch_it + get_it is the recommended foundation. Add command_it and listen_it when you need advanced features. Each package works independently.

Explore the ecosystem β†’

Learn More #

πŸ“– Documentation #

πŸ’¬ Community & Support #

Contributing #

Contributions are welcome! Please read the contributing guidelines before submitting PRs.

License #

MIT License - see LICENSE file for details.


Part of the flutter_it ecosystem β€” Build reactive Flutter apps the easy way. No codegen, no boilerplate, just code.

198
likes
150
points
7.37k
downloads
screenshot

Publisher

verified publisherflutter-it.dev

Weekly Downloads

The simple state management powered by get_it. It allows to observe changes of objects inside the get_it service locator and rebuild the UI accordingly.

Repository (GitHub)
View/report issues

Topics

#state-management #dependency-injection #architecture #get-it

Documentation

API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

flutter, get_it, listen_it

More

Packages that depend on watch_it