reactive_flutter 1.0.5 copy "reactive_flutter: ^1.0.5" to clipboard
reactive_flutter: ^1.0.5 copied to clipboard

A lightweight auto-tracking reactive state management library for Flutter.

reactive_flutter banner

pub package likes popularity pub points

A lightweight auto-tracking reactive state management library for Flutter.

reactive_flutter provides:

  • Reactive state containers
  • Automatic widget rebuild tracking
  • Lightweight dependency injection
  • Page-based pagination
  • Cursor-based pagination
  • Reactive search
  • Reactive logger
  • Minimal boilerplate
  • Zero code generation

Wiki #


About #

reactive_flutter is designed to provide a lightweight and minimal reactive architecture for Flutter applications.

It focuses on:

  • Simplicity
  • Performance
  • Automatic dependency tracking
  • Minimal boilerplate
  • Easy integration

Features #

✅ Automatic dependency tracking  
✅ Lightweight and fast  
✅ No `BuildContext` required for state access  
✅ No manual dependency lists  
✅ No code generation  
✅ Page-based pagination  
✅ Cursor-based pagination  
✅ Reactive search with debounce  
✅ Reactive logger  
✅ Simple dependency injection  
✅ Easy to learn and use
✅ Background isolate task execution  
✅ Reactive isolate task state  
✅ Heavy computation without UI freeze  
✅ Generic isolate task payloads   

Quick Start #

final Reactive<int> counter = Reactive<int>(0);

Watch(
  builder: () {
    return Text('${counter.value}');
  },
)

Update state:

counter.value++;

Reactive State #

Reactive<T> is a lightweight reactive value holder.

Whenever the value changes, widgets that depend on it automatically rebuild.


Create Reactive Values #

final Reactive<int> counter = Reactive<int>(0);

final Reactive<String> title = Reactive<String>('Flutter');

final Reactive<bool> isDark = Reactive<bool>(false);

Reading Values #

Use .value to access the current value.

print(counter.value);

Updating Values #

counter.value++;

isDark.value = true;

Silent Updates #

Use setSilent() to update a value without notifying listeners.

counter.setSilent(100);

Watch Widget #

Watch automatically rebuilds whenever a reactive value used inside the builder changes.

No dependency list is required.


Basic Example #

Watch(
  builder: () {
    return Text('${counter.value}');
  },
)

Multiple Reactive Dependencies #

Watch(
  builder: () {
    return Column(
      children: [
        Text('${counter.value}'),

        Text(title.value),

        Switch(
          value: isDark.value,
          onChanged: (value) {
            isDark.value = value;
          },
        ),
      ],
    );
  },
)

Conditional Tracking #

Dependencies are tracked automatically based on what is accessed during build.

Watch(
  builder: () {
    return isDark.value
        ? const Text('Dark Mode')
        : const Text('Light Mode');
  },
)

Only the active branch is subscribed.


Nested Watch Example #

Watch(
  builder: () {
    return Column(
      children: [
        Watch(
          builder: () {
            return Text(
              counter.value.toString(),
            );
          },
        ),

        Watch(
          builder: () {
            return Text(title.value);
          },
        ),
      ],
    );
  },
)

Dependency Injection #

ReactiveInjector is a lightweight service locator.

Supports:

  • Singleton registration
  • Transient registration
  • Dependency lookup
  • Reset
  • Unregister
  • Clear all

Register Singleton #

ReactiveInjector.singleton<ApiService>(() => ApiService());

Retrieve dependency:

final ApiService api = ReactiveInjector.find<ApiService>();

Register Transient #

ReactiveInjector.transient<UserRepository>(() => UserRepository());

Check Registration #

final bool exists = ReactiveInjector.isRegistered<ApiService>();

Reset Singleton #

ReactiveInjector.reset<ApiService>();

Unregister Dependency #

ReactiveInjector.unregister<ApiService>();

Clear All Dependencies #

ReactiveInjector.clear();

Page-Based Pagination #

ReactivePagination<T> helps manage paginated APIs using page numbers.


Create Pagination Controller #

final ReactivePagination<User> pagination = ReactivePagination<User>(
  perPage: 20,
  fetcher: (page, perPage) async {
    return api.fetchUsers(page, perPage);
  },
);

Initialize Pagination #

await pagination.init();

Refresh Pagination #

await pagination.refresh();

Load More #

await pagination.fetchMore();

Watch Pagination State #

Watch(
  builder: () {
    if (pagination.isLoading) {
      return const CircularProgressIndicator();
    }

    return ListView.builder(
      itemCount: pagination.items.length,
      itemBuilder: (context, index) {
        final User user = pagination.items[index];

        return ListTile(title: Text(user.name));
      },
    );
  },
)

Scroll Pagination Example #

class UsersPage extends StatefulWidget {
  const UsersPage({super.key});

  @override
  State<UsersPage> createState() => _UsersPageState();
}

class _UsersPageState extends State<UsersPage> {
  final ScrollController controller =ScrollController();

  final ReactivePagination<User> pagination = ReactivePagination<User>(
    perPage: 20,
    fetcher: (page, limit) async {
      return api.fetchUsers(page, limit);
    },
  );

  @override
  void initState() {
    super.initState();

    pagination.init();

    controller.addListener(() {
      if (controller.position.pixels >=
          controller.position.maxScrollExtent -
              200) {
        pagination.fetchMore();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Watch(
      builder: () {
        return ListView.builder(
          controller: controller,
          itemCount: pagination.items.length,
          itemBuilder: (context, index) {
            final User user = pagination.items[index];

            return ListTile(title: Text(user.name));
          },
        );
      },
    );
  }
}

Cursor-Based Pagination #

ReactiveCursorPagination<T, C> supports cursor-based APIs.

Examples of cursor types:

  • String
  • int
  • DateTime
  • DocumentSnapshot (Firebase Firestore)
  • Firestore document snapshots
  • Custom models

Create Cursor Pagination #

final ReactiveCursorPagination<User, String>
    pagination =
    ReactiveCursorPagination<User, String>(
  perPage: 20,
  fetcher: (perPage, cursor) async {
    return api.fetchUsers(perPage, cursor);
  },
);

PaginationResult #

PaginationResult<User, String>(
  items: users,
  nextCursor: nextCursor,
)

Cursor Pagination State #

pagination.items
pagination.cursor
pagination.isLoading
pagination.isMoreLoading
pagination.hasMore
pagination.error
pagination.totalFetched
pagination.isEmpty

Reactive Search #

ReactiveSearch<T> provides debounced reactive searching.

Features:

  • Debounced queries
  • Idle/loading/error states
  • Stale request protection
  • Automatic rebuilding

Create Search Controller #

final ReactiveSearch<User> search =
    ReactiveSearch<User>(
  debounceMs: 500,
  minLength: 2,
  fetcher: (query) async {
    return api.searchUsers(query);
  },
);

TextField(onChanged: search.onChanged)

await search.search('flutter');

search.clear();

Watch Search State #

Watch(
  builder: () {
    if (search.isLoading) {
      return const CircularProgressIndicator();
    }

    if (search.isEmpty) {
      return const Text('No results');
    }

    return ListView.builder(
      itemCount: search.results.length,
      itemBuilder: (context, index) {
        final User user = search.results[index];
        return ListTile(title: Text(user.name));
      },
    );
  },
)

Reactive Isolate Tasks #

ReactiveIsolateTask<T> provides reactive isolate execution for heavy background operations.

Features:

  • Background isolate execution
  • Reactive loading state
  • Reactive error handling
  • Generic reusable task payloads
  • Non-blocking UI updates

Create Isolate Task #

final ReactiveIsolateTask<int> task = ReactiveIsolateTask<int>();

Run Task #

await task.run<int>(
  ReactiveTaskPayload(input: 1000000, allback: heavyCalculation),
);

Watch Task State #

Watch(
  builder: () {
    if (task.isLoading) {
      return const CircularProgressIndicator();
    }

    if (task.error != null) {
      return Text(task.error.toString());
    }

    return Text('Result: ${task.data}');
  },
)

Handle Errors #

await task.run<String>(
  ReactiveTaskPayload(
    input: 'data',
    callback: (value) {
      throw Exception('Something failed');
    },
  ),
);

print(task.error);

Heavy Task Example #

int heavyCalculation(int total) {
  int sum = 0;

  for (int i = 0; i < total; i++) {
    sum += i;
  }

  return sum;
}

await task.run<int>(
  ReactiveTaskPayload(
    input: 10000000,
    callback: heavyCalculation,
  ),
);

Reactive Logger #

ReactiveLogger is a lightweight persistent logger with reactive state support.

Features:

  • File-based logs
  • Auto-clear policies
  • Buffered writes
  • Console output
  • Error & stack trace logging
  • Reactive logger state

Initialize Logger #

final ReactiveLogger logger = ReactiveLogger(fileName: 'app_logs', clearPolicy: ClearPolicy.weekly);
await logger.init();

Write Logs #

logger.debug('Debug message');

logger.info('User logged in');

logger.warning('Slow API response');

logger.error('Request failed', error: exception, stack: stackTrace);

logger.fatal('Critical failure');

Read Logs #

  LoggerView.open(context, logger: logger);

Clear Logs #

await logger.clearFile();

Delete Logs #

await logger.deleteFile();

Logger State #

logger.value.totalLogs
logger.value.lastCleared
logger.value.isReady

API Overview #

Reactive #

Function Description
value Get or update reactive value
setSilent() Update without notifying
toString() Debug string

Watch #

Property Description
builder Auto-tracked widget builder

ReactiveInjector #

Function Description
singleton() Register singleton
transient() Register transient
find() Resolve dependency
isRegistered() Check registration
reset() Reset singleton
unregister() Remove dependency
clear() Remove all dependencies

ReactivePagination #

Function Description
init() Load first page
refresh() Reload pagination
fetchMore() Load next page

ReactiveCursorPagination #

Function Description
init() Load first cursor page
refresh() Reload pagination
fetchMore() Load next cursor page

ReactiveSearch #

Function Description
onChanged() Debounced search
search() Manual search
clear() Reset search
results Current results
isLoading Loading state
isIdle Idle state
isEmpty Empty state
error Current error

ReactiveIsolateTask #

Function Description
run() Run isolate task safely
runOrThrow() Run isolate task and throw error
reset() Reset task state
isLoading Current loading state
data Latest task result
error Latest task error

ReactiveLogger #

Function Description
debug() Write debug log
info() Write info log
warning() Write warning log
error() Write error log
fatal() Write fatal log
clearFile() Clear log file
deleteFile() Delete log file
readRaw() Read raw log
readLines() Read log lines

Performance #

reactive_flutter is designed to stay lightweight and fast.

Why it performs well #

  • No reflection
  • No code generation
  • Fine-grained rebuild tracking
  • Minimal allocations
  • Conditional dependency tracking
  • Only subscribed widgets rebuild
  • Background isolate execution for heavy operations
  • Large file parsing without blocking UI
  • Reactive async task state management

Architecture #

Reactive<T>
    ↓
ReactiveTracker
    ↓
Watch Widget
    ↓
Automatic Rebuild

How it works #

  1. Watch starts dependency tracking
  2. Accessed reactive values register themselves
  3. Watch subscribes only to used reactives
  4. Changed reactives rebuild subscribed widgets

Comparison #

Feature reactive_flutter GetX Riverpod Provider
Auto tracking ⚠️ Partial
Code generation ⚠️ Optional
Boilerplate Very Low Low Medium Medium
Dependency injection
Pagination helpers
Reactive search
Reactive logger
Reactive isolate tasks
Automatic rebuild tracking ⚠️ Partial
Zero-config watchers ⚠️
Learning curve Easy Easy Medium Easy
Lightweight ⚠️ ⚠️
No BuildContext access

Best Practices #

  • Keep reactive values focused and small
  • Prefer multiple small reactives
  • Use nested Watch widgets for granular rebuilds
  • Dispose controllers when needed
  • Avoid unnecessary global state

When to Use reactive_flutter #

reactive_flutter works especially well for:

  • Small to medium apps
  • Utility applications
  • MVPs & prototypes
  • Admin panels
  • Feature modules
  • Teams preferring lightweight architecture

Advanced Reactive Example #

final Reactive<List<String>> todos = Reactive<List<String>>([]);

void addTodo(String value) {
  todos.value = [ ...todos.value, value ];
}

void removeTodo(String value) {
  todos.value = todos.value.where((e) => e != value).toList();
}

Unit Testing Example #

void main() {
  test(
    'Reactive value updates correctly',
    () {
      final Reactive<int> counter = Reactive<int>(0);

      counter.value = 5;

      expect(counter.value, 5);
    },
  );
}

FAQ #

Does this use code generation? #

No.

reactive_flutter works without generators or build_runner.


Does Watch rebuild the whole app? #

No.

Only widgets subscribed to changed reactive values rebuild.


Can I use it with existing architectures? #

Yes.

Works well with:

  • Clean Architecture
  • MVVM
  • MVC
  • Feature-first architecture

Does it support async state? #

Yes.

You can store async results, pagination state, and API responses inside reactive values.


Is it production ready? #

Yes.

The library is designed to be lightweight, predictable, and production friendly.


Roadmap #

Planned future improvements:

  • ❌ Computed reactive values
  • ❌ Reactive collections
  • ❌ DevTools integration
  • ❌ Async reactive helpers
  • ❌ Stream bindings
  • ❌ Form utilities
  • ❌ Persistent storage helpers
  • ❌ Flutter Web optimizations
  • ❌ Isolate task pooling
  • ❌ Parallel isolate execution helpers
  • ❌ Cancelable isolate tasks

Contributing #

Contributions are welcome.

Setup #

git clone <repository>
cd reactive_flutter
flutter pub get

Run Tests #

flutter test

Format Code #

dart format .

License #

MIT License © V Developer

2
likes
160
points
14
downloads

Documentation

API reference

Publisher

verified publishervdeveloper.tech

Weekly Downloads

A lightweight auto-tracking reactive state management library for Flutter.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, path_provider

More

Packages that depend on reactive_flutter