⚑ reactivity

Logo

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 reactivity is its seamless support for Dart Records via ValueState.

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