rebuilder pub package

Rebuilder is an easy and minimalistic state management library for Flutter.

It consists of:

  • A DataModel class to extend to create a class where lives the data and the business logic for the UI.

  • A DataModelProvider that provides this model to the widgets tree by using an InheritedWidget.

  • A RebuilderState that holds the state of a Rebuilder widget.

  • The Rebuilder widget that represents the entity which rebuilds every time the rebuild method of the associated RebuilderState's state property is called.

  • The RebuilderObject: an object bound to a RebuilderState in order to rebuild the Rebuilder widget associated to this state whenever a new value is set.

Examples built with this library:
  • Rebuilder example. Check out the example app to know how to:

    • Implement a counter
    • Use the DataModel to separate the UI from the business logic
    • Implement a dynamic theme changer with a RebuilderObject
    • Bind a function to a RebuilderObject
    • Sharing data between widgets
    • Update only a subtree of widgets
  • Quiz game: a simple trivia game built with Flutter and this package.

Getting started

1. Define a DataModel
class CountersModel extends DataModel {
  CountersModel() {

    // Initialize the instance of the `RebuilderObject` with
    // with an instance of a `RebuilderState` that will be bound
    // to a `Rebuilder` widget.
    counterDown = RebuilderObject<int>.init(
        rebuilderState: counterDownState,
        initialData: 100,
        onChange: _onCounterDownChange);
  final counterUpState = RebuilderState();
  final counterDownState = RebuilderState();
  final counterMulState = RebuilderState(); 

  int counterUp = 0;
  int counterMul = 2;
  RebuilderObject<int> counterDown;

  void incrementCounterUp() {

  void decrementCounterDown() {

    // Using the `RebuilderObject` the `rebuild` method of the
    // counterDownState will automatically be called.
    // states.counterDownState.rebuild();

  void _onCounterDownChange() {
    print('Value changed: ${counterDown.value}');

  void dispose() {}
2. Provide the CountersModel by using the DataModelProvider widget
final countersModel = CountersModel()

          dataModel: countersModel,
          child: const CountersPage(),
3. Get the CountersModel instance from the context of a widget in the tree
  Widget build(BuildContext context) {
    final countersModel = DataModelProvider.of<CountersModel>(context);
4. Bind the RebuilderState instances to the Rebuilder widgets in the view
    dataModel: countersModel,
    rebuilderState: countersModel.counterUpState,
    builder: (state, data) {
      // Accessing to `counterUp` in the `DataModel`
      // derived class provided through the `data` parameter
      return Text('${data.counterUp}');
      // It is possible to directly access to `counterUp`
      // without using the `dataModel` parameter:
      // builder: (state, _) {
      // return Text('${countersModel.counterUp}');
  child: const Text('+'),
  onPressed: countersModel.incrementCounterUp,

  dataModel: countersModel.counterDown,
  rebuilderState: countersModel.counterDownState,
  builder: (state, data) {
    return Text('${data.value}');
  child: const Text('-'),
  onPressed: countersModel.decrementCounterDown,

  dataModel: countersModel,
  rebuilderState: countersModel.counterMulState,
  builder: (state, data) {
    return Column(children: <Widget>[
          child: const Text('*'),
          onPressed: () {
            data.counterMul *= 2;
            if (data.counterMul > 65536) {
              data.counterMul = 2;