β‘ reactivity
A minimal and elegant state management solution for Flutter.
Rebuild only what matters β with zero boilerplate.
β Built for performance
π§ Easy to learn
π― Fully compatible with Flutter's widget tree
π Ideal for UI-driven apps
𧨠The Power of ValueState + Dart Records
The biggest highlight of
reactivityis its seamless support for Dart Records viaValueState.
With ValueState, you can manage multiple related state variables β like name, age, and email β using a single named record.
π€― Goodbye boilerplate, hello Named Records!
final user = ValueState<({String name, int age, bool isAdmin})>();
ReactiveState(user.on(
(u) => Text('Name: ${u.name}, Age: ${u.age}, Admin: ${u.isAdmin}'),
));
user.refreshWith((name: 'Felipe', age: 30, isAdmin: true));
βοΈ No classes
βοΈ Fully typed
βοΈ Instantly reactive
βοΈ Native Dart syntax
If you love Dart's record syntax β especially named records β this will feel like magic.
β¨ Features
- π
refresh()β triggers rebuilds globally or by key - π¦
refreshStatus()β reactive flow based on enum-like global status - π§±
ValueState,InitedState,VoidStateβ simple state containers with builder linkage - π§©
Reactive,ReactiveStatus,ReactiveState,ReactiveShowβ widgets that rebuild declaratively - β
ReactiveNullable,ReactiveNullableListβ null-safe conditionals with expressive UI fallback
π§ Getting Started
Add the dependency:
dependencies:
reactivity: ^1.0.0
Import in your Dart code:
import 'package:reactivity/reactivity.dart';
π Usage
Reactive widget (global rebuild)
int counter = 0;
Reactive(() => Text('Counter: $counter'));
// later
counter++;
refresh();
Reactive key (rebuild one widget only)
final myKey = ReactiveKey();
Reactive(
() => Text("Hello"),
reactiveKey: myKey,
);
// later
refreshOnly(myKey);
π§± Other State Tools
InitedState
final name = InitedState<String>("Kaian");
ReactiveState(name.on((value) => Text("Hello $value")));
// Update
name.refreshWith("Felipe");
ValueState (primitive or nullable types)
final count = ValueState<int>();
ReactiveState(count.on((value) => Text('Count: $value')));
// Initialize or update
count.refreshWith(1);
count.refreshUpdate((value) => value! + 1);
VoidState (no data, just trigger)
final trigger = VoidState();
ReactiveState(trigger.on(() => Text("Triggered!")));
// Trigger it
trigger.refresh();
π¦ ReactiveStatus
enum Status { loading, success, error }
refreshStatus(Status.loading);
ReactiveStatus<Status>(
cases: {
Status.loading: () => CircularProgressIndicator(),
Status.success: () => Text("Done!"),
Status.error: () => Text("Oops"),
},
defaultCase: () => Text("Idle"),
);
π Conditional builders
ReactiveShow
bool isLogged = false;
ReactiveShow(
showIf: () => isLogged,
builder: () => Text("Welcome"),
elseShow: Text("Login required"),
);
// Later
isLogged = true;
refresh();
ReactiveNullable
String? username;
ReactiveNullable<String>(
value: username,
builder: (name) => Text("Hi $name"),
ifNull: Text("No user"),
);
// Update
username = "Felipe";
refresh();
ReactiveNullableList
List<String>? items;
ReactiveNullableList<String>(
values: items,
builder: (list) => ListView(children: list.map(Text.new).toList()),
ifNull: CircularProgressIndicator(),
ifEmpty: Text("No items"),
);
β
Why use reactivity?
- π Best-in-class support for Dart Named Records
- π§Ό Simple, focused API
- π« No context, no classes, no scopes
- π― Works with Flutterβs widget tree naturally
- π¬ Declarative, explicit, beautiful
π¬ Contributing
Feel free to open issues, suggest features or contribute pull requests.
π§Ύ License
MIT License Β© Felipe Kaian