2.1.0 • Public • Published


    Redux made easy (with a plug and play approach)

    Removing the boilerplate code in setting up a store & actions

    npm version npm downloads Build Status gzip size Coverage Status Known Vulnerabilities compatible with preact-redux compatible with reselect Cookbook


    I created this utility to allow you to get up and running with Redux in a fraction of the time!

    Plug & Play

    • No wiring together of actions & reduces
    • No hardcoding actions types
    • No action creator or dispatcher to worry about
    • Easy Async for calling APIs
    • Easy initialize for parts of your store
    • Easy install = works as the same as other redux middleware
    • Pure JS no external dependencies!
    • SuperSmall: under 3k (minify + gzip)

    Have an existing project? No worries. Drop it in, to work along side the traditional redux way.

    Live Demo / Demo Source

    If you like it, ★ it on github and share 🍻


    In Redux your reducer returns a state object. This is very straight forward, but makes dealing with asynchronous updates quite tricky (there are more than 60 different libraries tackling this problem).

    redux-auto fixes this asynchronous problem simply by allowing you to create an "action" function that returns a promise. To accompany your "default" function action logic.

    asynchronous: example

    1. No need for other Redux async middleware. e.g. thunk, promise-middleware, saga
    2. Easily allows you to pass a promise into redux and have it managed for you
    3. Allows you to co-locate external service calls with where they will be transformed
    4. Naming the file "init.js" will have it called once at app start. This is good for loading data from the server to warm up you client cache.


    *Redux-Auto was created to work with Webpacks


    1. Create a folder to represent your store
      • This is where the data, logic & flow control of the application lives. This can be named whatever, just point to it with webpacks - require.context
    2. In this folder you will create folders to represent each attribute on the store
      • For example. the "user" folder will create an attribute of 'user'
      • the JS files within the folder are actions that can be fired to change the shape of user.
    3. Create an index.js file to set default values
      • export default is a catch all reducer function (if an action cant be found)
      • export "before" & "after" as lifecycle functions
    4. Create js files with the name of the action you want it mapped to
      • export default is the reducer function
      • export "action" function. Is an action-middleware that will allow you to create promises
    5. You can create an init.js It will be automatically run once after store created
      • using this to initialize from an API

    Example layout:

    └── store/ (1)
        └──user/ (2)
           └── index.js (3)
           └── changeName.js (4)
           └── init.js (5)


    Example of setup file

    Inside your setup file *Web-App

    import { auto, reducers } from 'redux-auto';
    // load the folder that hold you store
    const webpackModules = require.context("./store", true, /\.js$/);
                                    // build 'auto' based on target files via Webpack
    const middleware = applyMiddleware( auto(webpackModules, webpackModules.keys()))
    const store = createStore(combineReducers(reducers), middleware );

    Inside your setup file *React-Native

    ➡ If you want to use Redux-auto in a React-Native project. You will just need to install the babel-plugin-redux-auto to allow to dynamic importing of your store.

    1. npm i babel-plugin-redux-auto
    2. Add 'babel-plugin-redux-auto' to your plugins within your babel config

    Now back to the setup...

    import { auto, reducers } from 'redux-auto';
    // load the folder that hold you store
    import nativeStore from './store/*'
    const middleware = applyMiddleware( auto(nativeStore))
    const store = createStore(combineReducers(reducers), middleware );

    Using along side an existing Redux setup.

    // import your exiting reducers
    import reducers from './reducers';
    // include mergeReducers
    import { auto, mergeReducers } from 'redux-auto';
    // pass into: reducers >> mergeReducers >> combineReducers
    const store = createStore(combineReducers(mergeReducers(reducers)), middleware );

    Using along side other Redux middleware. *Web-App

    import logger from 'redux-logger';
    import { auto, reducers } from 'redux-auto';
                        // pass all the middlewares in a normal arguments
    const middleware = applyMiddleware( logger, auto(webpackModules, webpackModules.keys()))
    const store = createStore(combineReducers(reducers), middleware );

    Using along side other Redux middleware. *React-Native

    import logger from 'redux-logger';
    import { auto, reducers } from 'redux-auto';
                        // pass all the middlewares in a normal arguments
    const middleware = applyMiddleware( logger, auto(nativeStore))
    const store = createStore(combineReducers(reducers), middleware );

    actions are available in the UI

    Just import "redux-auto" and the actions are automatically available by default

    import actions from 'redux-auto'
    //action[folder][file]( data )

    action files

    The action file lives within your attribute folder and becomes the exposed action. The default export should be a function that will take 1) your piece of the state 2) the payload data

    Example: of an action to update the logged-in users name

    // e.g. /store/user/changeUserName.js
    export default function (user, payload) {
      return Object.assign({}, user,{ name : } );

    ★ Sometimes we want to talk to the server. This is done by action-middleware

    This is done by exporting a function named "action" that returns a promise. The default function will now receive a 3rd argument "state". With the 2nd argument being the payload used to create the request

    Example: saving the uses name to the server

    // /store/user/changeUserName.js
    export default function (user, payload, stage, data) {
        case 'FULFILLED':
         // ...
        case 'REJECTED':
         // ...
        case 'PENDING':
        default :
         // ...
      return user;
    export function action (payload,user){
        return fetch('/api/foo/bar/user/'+payload.userId)

    An alternative declaration for the same as above

    // /store/user/changeUserName.js
    export function pending (posts, payload){
      return posts
    export function fulfilled (posts, payload, serverPosts){
      return serverPosts
    export function rejected (posts, payload, error){
      return posts;
    export function action (payload,posts){
        return fetch('/api/foo/bar/user/'+payload.userId)

    chaining actions together

    You chain actions back-to-back by setting an "chain" property on the exported function.

    Attach a function as the "chain" property

    Example: /store/user/getInfo

    export function fulfilled (user, payload, userFromServer){
      return userFromServer;
    } fulfilled.chain = (user, payload, userFromServer) => actions.nav.move({page:"home"})
    export function rejected (user, payload, userFromServer){
      return userFromServer;
    } rejected.chain = actions.user.reset
    export function pending (user, payload){
      return user
    export function action (payload){
        return fetch('/api/foo/bar/user/'+payload.userId)

    If you pass your own function. Like with the 'fulfilled' example. It will be passed all the arguments, the same as the host function was.

    Else you can pass thought an "redux-auto" action function. Like with the 'rejected' example. It will called without any arguments.

    So calling "actions.user.getInfo({userId:1})" will automatically call actions.nav.move with the host arguments OR actions.user.reset *with out arguments.

    chaining to dispatcher

    Chained functions can call the dispatcher directly.To trigger the dispatcher from your chain you need to return an object with a type and payload


    import { push, replace } from 'react-router-redux';
    export default function highLightFirend(friendID, {id}) {
      return id;
    // This will call the 3rd party "router" reducer
    highLightFirend.chain = (friendID, {id})=>{
      const searchParams = new URLSearchParams(;
      if (!id) {
        const url = window.location.pathname+"#"+searchParams.toString()
        return replace(url) // { type: '@@router/LOCATION_CHANGE',  payload: { ... } }
        searchParams.set("resource", id);
        const url = window.location.pathname+"#"+searchParams.toString()
       return push(url) // { type: '@@router/LOCATION_CHANGE',  payload: { ... } }

    cancel an action

    You can cancel an action from with-in the action .js file before it starts by not returning any value


    export function action (payload,user){
      if( ===
         return fetch('/api/foo/bar/user/'+payload.userId)

    index files

    "index" files are need for each attribute folder you make.

    This file can exposes three funtions

    1. before
    2. default
    3. after

    You can also istening for other actions from other parts of the store.


    Fires on every action, to tweek the payload that will be passed to you logic functions.

    // add a time stamp to the payload that will be recived by user reduced
    export function before(user, action){
        return Object.assign({},action.payload,{ timeStamp : new Date() })


    This is a normal redux reducer function, being passed the previousState and the action.

    export default function user(user = {name:"?"}, action) {
      return user;

    ⚠ This function will be fired on all actions, EXCEPT for actions that are handled by a specific action file in this reducer folder.

    Lets understand this with an example:


     │  └── index.js
     │  └── changeName.js
        └── index.js
        └── delete.js


    import actions from 'redux-auto'

    The default functions for store/user/changeName.js & store/post/index.js will be fired.

    store/user/index.js was NOT called because there is a specific action file a to handle it for user.


    Fires after every action, allowing you to change your piece of the state.

    import actions from 'redux-auto'
    // automatically keep a log of all actions against user
    export function after(newUserValues, action, oldUserValues){
        const changes = {}
        if(action.type in actions.user) // log if this is a user action!
            changes.log = newUserValues.concat(log,[{action.type:action.payload}])
        return Object.assign({}, newUserValues, changes)

    listening for other actions

    There are two built-in ways to detect other actions from within your index. 1)You can find if the current fire action that you have received matches a specific action and 2) You can find if their current action is part of another piece of the store.

    1. To find if the correct action is a specific action. Import the actions as you normally would and do a loose equality check.

    Example: We want to have a count of how many post our user has done

    import actions from 'redux-auto'
    export default function user(user = {name:"?", posts:0}, action) {
      // You can check on each state of an asynchronous action
      if( == action.type){
        return Object.assign({},user,{posts:user.posts+1})
        // And non-synchronous actions can be checked directly
      } else if(actions.posts.something == action.type){
        // ... do some work ...
      return user;
    1. If you wish to listen to all actions from a specific part of the store. You can use the in keyword.

    Example: We wish to log all post actions

    import actions from 'redux-auto'
    export default function logging(log = [], action) {
      // test if the action type is within the posts
      if(action.type in actions.posts){
        return [...log, action]
      return log;

    handling async actions in your UI

    redux-auto has a built in mechanism to flag what stage an async action is in..

    if the state that you returned from your reduce function is an object or array. redux-auto will transparently attach a "loading" property representing all async actions.

    The "loading" flag can have 1 of 4 values

    1. undefined : the async action has not been fired yet
    2. true : the action is in progress
    3. false : the action has completed successfully
    4. error : an error occurred and here is the error object + a "clear" function to reset the async to undefined
    • Note: The async action will also have the clear function if at any time you want to reset the "loading" property. is the async function and will clear the "loading" property.


    // user = { name:"tom" }
    JSON.stringify(state.user) // "{ "name":"tom" }"
 // = undefined

 // = true
    // when the request or promuse completed
 // = false
    // if the was a problem. it will be was to the error object
 // = Error("some problem")
    // + with an Error, there will also be a "clear" function to set the "loading" back to undefined
    // e.g.

    handling async actions in your ui:- example

    smart actions

    smart actions is an options flag that handly actions function more intelligently.

    Currently facilitates graphql and fetch responses returned by action's promises.

    To enable:

    import { auto } from 'redux-auto';

    This will now parce fetch and graphQL errors into your rejected function. As well as parsing the json if available


    If you want to use a testing frameworking. There is helper funcsion /test/fsModules

    For jest example:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { createStore, applyMiddleware, combineReducers } from 'redux';
    import { auto, reducers } from 'redux-auto';
    import fsModules from 'redux-auto/test/fsModules'
    import App from './Main';
    import path from 'path';
    import fs from 'fs';
    const storePath = path.join(path.dirname(fs.realpathSync(__filename)), 'store');
    const webpackModules = fsModules(storePath)
    const middleware = applyMiddleware( auto(webpackModules, webpackModules.keys()))
    const store = createStore(combineReducers(reducers), middleware );
    it('renders without crashing', () => {
      const div = document.createElement('div');
      ReactDOM.render(<App store={store} />, div);



    npm i redux-auto

    DownloadsWeekly Downloads






    Unpacked Size

    145 kB

    Total Files


    Last publish


    • codemeasandwich