Flutter Community: redux_undo

Build Status codecov pub package


This package will make your redux store undoable.

Things to come in the future

  • Support for making only a slice of the state undoable
  • more examples and documentation


define the dependency in your pubspec.yaml file:

  redux_undo: ^1.0.0+1

update your applications packages by running

pub get

or when using flutter as a framework

flutter pub get

import the package to use in the file you are setting up redux:

import 'package:redux_undo/redux_undo.dart';


redux_undo will slightly modify your state by adding a new properties-layer at the root of the store. The final structure will look like this:

/// when accessed directly from the store, store.state will have this structure
UndoableHistory<S> state = {
  past: <S>[],
  present: null, // <-- the current state of the app
  future: <S>[],
  latestUnfiltered: null // <-- basically equals present, to store a mutual state before storing it into past or future 


Because it modifies the initial state you need to initiate redux_undo when initiating the redux store. This is done by calling 2 separate functions:

/// to wrap the root reducer
Reducer<UndoableState<S>> createUndoableReducer<S>(Reducer<S> reducer, { UndoableConfig config });

/// to wrap the Root state of your app.
UndoableState<S> createUndoableState<S>(S initialState, bool ignoreInitialState);

Here is an example of how this can be done in a flutter app:

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'package:redux_undo/redux_undo.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  final Store<UndoableState<RootState>> store = Store<UndoableState<RootState>>(
    initialState: createUndoableState(RootState.initial(), false),

  Widget build(BuildContext context) {
    return StoreProvider<UndoableState<RootState>>(
      store: store,
      child: MaterialApp(
        title: 'Redux Undo Demo',
        home: const MyHomePage(),


redux_undo provides 4 basic actions

  • UndoableUndoAction - Standard-Action for undo

    Usage: store.dispatch(UndoableUndoAction())

  • UndoableRedoAction - Standard-Action for redo

    Usage: store.dispatch(UndoableRedoAction())

  • UndoableJumpAction - Standard-Action for jump (to past or to future)

    Usage: store.dispatch(UndoableJumpAction(index: -2)) // <- jumps 2 steps to the past (same as dispatching UndoableUndoAction twice)

    Usage: store.dispatch(UndoableJumpAction(index: 0)) // <- does nothing, since it just returns the current UndoableState

    Usage: store.dispatch(UndoableJumpAction(index: 2)) // <- jumps 2 steps to the future (same as dispatching UndoableRedoAction twice)

  • UndoableClearHistoryAction - Standard-Action for clearing the history


It is possible to provide a configuration object to the UndoableState instantiation like this:

final UndoableConfig config = UndoableConfig(
  limit: 100,
  blackList: <Type>[
  whiteList: <Type>[

Then pass it to the createUndoableReducer function like this:

final Store<UndoableState<RootState>> store = Store<UndoableState<RootState>>(
    createUndoableReducer<RootState>(rootReducer, config: config),
    initialState: createUndoableState(RootState.initial(), false),

These are the options the UndoableConfig class provides:

  • int limit: limits the length of the UndoableState.past List and with this ultimately the length of UndoableState.future as well
    • default value => 10
  • List whiteList: actions in this list need to be extended from one of the provided redux_undo actions and will fire the original rootReducer after performing the action they extended from without updating UndoableState.past or UndoableState.future