v1.1.0 Released

reactivThe GetX alternative that does it right

Production-ready reactive state management for Flutter with zero boilerplate, built-in undo/redo, computed values, debounce/throttle, and a robust logger framework. ~150 APIs vs GetX's 2400+.

Quick Example

See how easy it is to add reactive state management to your Flutter app:

1

1. Install

dependencies:
  reactiv: ^1.1.0
2

2. Create Controller

class CounterController extends ReactiveController {
  final count = ReactiveInt(0);
  
  void increment() => count.value++;
}
3

3. Use ReactiveStateWidget

class CounterScreen extends ReactiveStateWidget<CounterController> {
  @override
  BindController<CounterController>? bindController() {
    return BindController(controller: () => CounterController());
  }
  
  @override
  Widget build(BuildContext context) {
    return ReactiveBuilder(
      reactiv: controller.count,
      builder: (context, count) {
        return Text('Count: $count');
      },
    );
  }
}
4

4. That's it!

// Zero boilerplate!
// Auto lifecycle management
// No memory leaks
// Type-safe reactive updates

Why Choose reactiv?

Everything you need for modern Flutter state management

â†Šī¸

Undo/Redo Support

Built-in history tracking with undo/redo functionality. NEW in v1.0.0!

History Tracking

Dart
final text = ReactiveString('Hello', enableHistory: true);

text.value = 'World';
text.value = 'Flutter';

text.undo(); // Back to 'World'
text.redo(); // Forward to 'Flutter'

print(text.canUndo); // true
print(text.canRedo); // false
īŋŊ

Computed Values

Auto-updating derived state that recomputes when dependencies change. NEW in v1.0.0!

Computed State

Dart
final firstName = 'John'.reactiv;
final lastName = 'Doe'.reactiv;

final fullName = ComputedReactive(
  () => '${firstName.value} ${lastName.value}',
  dependencies: [firstName, lastName],
);

firstName.value = 'Jane';
// fullName automatically updates to 'Jane Doe'!
âąī¸

Debounce & Throttle

Built-in performance optimization for search inputs and scroll events. NEW in v1.0.0!

Performance Optimization

Dart
// Debounce - wait for user to stop typing
final searchQuery = ReactiveString('');
searchQuery.setDebounce(Duration(milliseconds: 500));
searchQuery.updateDebounced('flutter'); // Waits 500ms

// Throttle - limit update frequency
final scrollPosition = ReactiveInt(0);
scrollPosition.setThrottle(Duration(milliseconds: 100));
scrollPosition.updateThrottled(150); // Max once per 100ms
īŋŊ

Robust Logger Framework

Production-ready logging with multiple levels, JSON formatting, and performance tracking. NEW in v1.0.1!

Advanced Logging

Dart
// Configure for your environment
Logger.config = kReleaseMode 
    ? LoggerConfig.production   // Minimal logging
    : LoggerConfig.development; // Verbose logging

// Multiple log levels
Logger.i('General information');
Logger.w('Warning - potential issue');
Logger.e('Error occurred', error: e, stackTrace: stack);

// Pretty JSON logging
Logger.json({'user': 'John', 'preferences': {'theme': 'dark'}});

// Performance timing
final data = await Logger.timed(
  () => api.fetchUsers(),
  label: 'API Call',
);
đŸŽ¯

ReactiveStateWidget (Recommended)

Automatic controller lifecycle management with zero boilerplate and no memory leaks.

Recommended Pattern

Dart
class CounterScreen extends ReactiveStateWidget<CounterController> {
  const CounterScreen({super.key});

  @override
  BindController<CounterController>? bindController() {
    // Automatically injects and disposes the controller
    return BindController(controller: () => CounterController());
  }

  @override
  Widget build(BuildContext context) {
    return ReactiveBuilder(
      reactiv: controller.count,
      builder: (context, count) {
        return Text('Count: $count');
      },
    );
  }
}
🧠

Smart Dependency Injection

Zero memory leaks with automatic cleanup and lazy loading for heavy controllers.

Smart Injection

Dart
// Register lazy builder - controller NOT created yet
Dependency.lazyPut(() => ExpensiveController());

// Controller created here, on first access
final controller = Dependency.find<ExpensiveController>();

// Fenix mode - auto-recreate after deletion
Dependency.put(MyController(), fenix: true);

// Check if registered
if (Dependency.isRegistered<MyController>()) {
  // Use it
}

Interactive Examples

Try these examples to see how reactiv works in practice

Examples

History Tracking

Learn about undo/redo support

Dart
final text = ReactiveString('Hello', enableHistory: true);

text.value = 'World';
text.value = 'Flutter';

text.undo(); // Back to 'World'
text.redo(); // Forward to 'Flutter'

print(text.canUndo); // true
print(text.canRedo); // false
Tags:undo/redo-support
Learn Moreâ€ĸ

Trusted by Developers

Join thousands of Flutter developers who chose Reactiv

~150 APIs
Package Size
vs GetX's 2400+ APIs
Zero
Memory Leaks
Smart dependency injection
Batched Updates
Performance
Optimized rebuilds
100%
Test Coverage
Battle-tested in production

What Developers Say

Real feedback from real developers

S
Sarah Chen
Senior Flutter Developer at TechCorp
"Reactiv transformed how we handle state in our Flutter apps. The API is so intuitive that our junior developers picked it up in minutes."
M
Mike Rodriguez
Mobile Team Lead at StartupXYZ
"We migrated from Provider to Reactiv and saw immediate performance improvements. The debugging tools are fantastic."
A
Alex Thompson
Flutter Consultant at Freelancer
"Finally, a state management solution that doesn't require a PhD to understand. Reactiv just makes sense."

The GetX alternative that does it right

Why developers are switching from GetX, Provider, and Riverpod to Reactiv

SolutionPackage SizeLearning CurveType SafetyDependency InjectionUndo/RedoComputed ValuesLogger Framework
Reactiv
~150 APIs
⭐⭐⭐⭐⭐
⭐⭐⭐⭐⭐
✅✅✅✅✅
GetX
2400+ APIs
⭐⭐⭐⭐⭐
⭐⭐⭐⭐⭐
âš ī¸âœ…âŒâŒâŒ
Provider
Medium
⭐⭐⭐⭐⭐
⭐⭐⭐⭐⭐
✅❌❌❌❌
Riverpod
Large
⭐⭐⭐⭐⭐
⭐⭐⭐⭐⭐
✅✅❌✅❌

Reactiv vs GetX: Code Comparison

See the difference in clarity and explicitness

Reactiv: Explicit Listening

ReactiveBuilder(
  reactiv: controller.count, // Explicit - you know what updates this
  builder: (context, count) {
    return Text('$count');
  },
)

You explicitly declare what ReactiveBuilder listens to

GetX: Implicit Listening

Obx(() {
  // Implicit - any reactive var here triggers rebuild
  final count = controller.count.value;
  return Text('$count');
})

Magic behavior - hard to debug which variable triggers rebuilds

Ready to Get Started?

Join thousands of developers building amazing Flutter apps with Reactiv