StoreKeeper

StoreKeeper is a state management library built for Flutter apps with focus on simplicity. It is heavily inspired by similar libraries in the JavaScript world. Here is a basic idea of how it works:

  • Single Store to keep app's data
  • Structured modifications to store with Mutations
  • Widgets listen to mutations to rebuild themselves
  • Enhance this process with Interceptors and SideEffects

Core of StoreKeeper is based on the InheritedModel widget from Flutter and it was initially developed as the backend for Kite in early 2018. Later it was detached to this library. Now it is in production for numerous other apps including Coin, Olam and Hackly.

Getting started

Add to your pubpsec:

dependencies:
  ...
  store_keeper: ^1.0.0

Create a store:

import 'package:store_keeper/store_keeper.dart';

class AppStore extends Store {
  int count = 0;
}

Define mutations:

class Increment extends Mutation<AppStore> {
  exec() => store.count++;
}

class Multiply extends Mutation<AppStore> {
  final int by;

  Multiply({required this.by});

  exec() => store.count *= by;
}

Listen to mutations:

@override
Widget build(BuildContext context) {
  // Define when this widget should re render
  StoreKeeper.listen(context, to: [Increment, Multiply]);

  // Get access to the store
  final store = StoreKeeper.store as AppStore;

  return Text("${store.count}");
}

Complete example:

import 'package:flutter/material.dart';
import 'package:store_keeper/store_keeper.dart';

// Build store and make it part of app
void main() {
  runApp(StoreKeeper(
    store: AppStore(),
    child: MyApp(),
  ));
}

// Store definition
class AppStore extends Store {
  int count = 0;
}

// Mutations
class Increment extends Mutation<AppStore> {
  exec() => store.count++;
}

class Multiply extends Mutation<AppStore> {
  final int by;

  Multiply({required this.by});

  exec() => store.count *= by;
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Define when this widget should re render
    StoreKeeper.listen(context, to: [Increment, Multiply]);

    // Get access to the store
    final store = StoreKeeper.store as AppStore;

    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: <Widget>[
            Text("Count: ${store.count}"),
            ElevatedButton(
              child: Text("Increment"),
              onPressed: () {
                // Invoke mutation
                Increment();
              },
            ),
            ElevatedButton(
              child: Text("Multiply"),
              onPressed: () {
                // Invoke with params
                Multiply(by: 2);
              },
            ),
          ],
        ),
      ),
    );
  }
}

Documentation

Libraries

store_keeper