diff --git a/__tests__/src/reducers/createActions.test.js b/__tests__/src/reducers/createActions.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..74b5755ba3511dfa2373b1867c56d53a889f79fe
--- /dev/null
+++ b/__tests__/src/reducers/createActions.test.js
@@ -0,0 +1,143 @@
+import {
+  createTableReducerActions,
+  createSingletonReducerActions,
+} from '../../../src/state/reducers/createActions';
+
+describe('table reducer actions', () => {
+  const actionTypes = {
+    create: 'CREATE_ITEM',
+    update: 'UPDATE_ITEM',
+    delete: 'DELETE_ITEM',
+    order: 'SET_ITEM_ORDER',
+  };
+
+  const idPrefix = 'item';
+
+  const defaultProps = {
+    foo: 'bar',
+  };
+
+  describe('createTableReducerActions', () => {
+    it('should return object with correct function names', () => {
+      const actionCreators = createTableReducerActions(actionTypes);
+      expect(actionCreators.createItem).toBeInstanceOf(Function);
+      expect(actionCreators.updateItem).toBeInstanceOf(Function);
+      expect(actionCreators.deleteItem).toBeInstanceOf(Function);
+      expect(actionCreators.setItemOrder).toBeInstanceOf(Function);
+    });
+  });
+
+  describe('create action creator', () => {
+    it('should return correct action type', () => {
+      const { createItem } = createTableReducerActions(actionTypes);
+      const action = createItem();
+      expect(action.type).toBe('CREATE_ITEM');
+    });
+
+    it('should set the passed id to the action', () => {
+      const { createItem } = createTableReducerActions(actionTypes, idPrefix, defaultProps);
+      const action = createItem({}, 'item-xyz');
+      expect(action.id).toBe('item-xyz');
+    });
+
+    it('should create an id if no id is given.', () => {
+      const { createItem } = createTableReducerActions(actionTypes, idPrefix, defaultProps);
+      const action = createItem();
+      expect(typeof action.id).toBe('string');
+    });
+
+    it('should merge default properties to payload', () => {
+      const { createItem } = createTableReducerActions(actionTypes, idPrefix, defaultProps);
+      const action = createItem();
+      expect(action.payload).toMatchObject(defaultProps);
+    });
+
+
+    it('should merge passed data object to payload', () => {
+      const { createItem } = createTableReducerActions(actionTypes, idPrefix, defaultProps);
+      const action = createItem({ bubu: 'kiki' });
+      expect(action.payload).toMatchObject({ foo: 'bar', bubu: 'kiki' });
+    });
+
+    it('passed data object can overwrite default props and id', () => {
+      const { createItem } = createTableReducerActions(actionTypes, idPrefix, defaultProps);
+      const action = createItem({ foo: 'kiki', id: 42 });
+      expect(action.payload).toEqual({ foo: 'kiki', id: 42 });
+    });
+  });
+
+  describe('update action creator', () => {
+    it('should return correct action type', () => {
+      const { updateItem } = createTableReducerActions(actionTypes);
+      const action = updateItem();
+      expect(action.type).toBe('UPDATE_ITEM');
+    });
+
+    it('should set the passed id to the action', () => {
+      const { updateItem } = createTableReducerActions(actionTypes);
+      const action = updateItem(33, {});
+      expect(action.id).toBe(33);
+    });
+
+    it('should set the data object to the action', () => {
+      const { updateItem } = createTableReducerActions(actionTypes);
+      const action = updateItem(33, { bubu: 'kiki' });
+      expect(action.payload).toEqual({ bubu: 'kiki' });
+    });
+  });
+
+  describe('delete action creator', () => {
+    it('should return correct action type', () => {
+      const { deleteItem } = createTableReducerActions(actionTypes);
+      const action = deleteItem();
+      expect(action.type).toBe('DELETE_ITEM');
+    });
+
+    it('should set the passed id to the action', () => {
+      const { deleteItem } = createTableReducerActions(actionTypes);
+      const action = deleteItem(33);
+      expect(action.id).toBe(33);
+    });
+  });
+
+  describe('order action creator', () => {
+    it('should return correct action type', () => {
+      const { setItemOrder } = createTableReducerActions(actionTypes);
+      const action = setItemOrder();
+      expect(action.type).toBe('SET_ITEM_ORDER');
+    });
+
+    it('should set the passed data object to payload', () => {
+      const { setItemOrder } = createTableReducerActions(actionTypes);
+      const action = setItemOrder([1, 2, 3]);
+      expect(action.payload).toEqual([1, 2, 3]);
+    });
+  });
+});
+
+describe('Singleton reducer actions', () => {
+  const actionTypes = {
+    update: 'UPDATE_ITEM',
+  };
+
+  describe('createSingletonReducerActions', () => {
+    it('should return object with correct function names', () => {
+      const actionCreators = createSingletonReducerActions(actionTypes);
+      expect(actionCreators.updateItem).toBeInstanceOf(Function);
+    });
+  });
+
+  describe('update action creator', () => {
+    it('should return correct action type', () => {
+      const { updateItem } = createSingletonReducerActions(actionTypes);
+      const action = updateItem();
+      expect(action.type).toBe('UPDATE_ITEM');
+    });
+
+    it('should set passe data object to payload', () => {
+      const { updateItem } = createSingletonReducerActions(actionTypes);
+      const action = updateItem({ bubu: 'kiki' });
+      expect(action.payload).toEqual({ bubu: 'kiki' });
+    });
+  });
+});
diff --git a/__tests__/src/reducers/createReducers.test.js b/__tests__/src/reducers/createReducers.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd420ff7e72022116542c4a48be07954b634ca91
--- /dev/null
+++ b/__tests__/src/reducers/createReducers.test.js
@@ -0,0 +1,155 @@
+import {
+  createTableReducer,
+  createSingletonReducer,
+} from '../../../src/state/reducers/createReducers';
+
+describe('table reducer', () => {
+  const actionTypes = {
+    create: 'CREATE_ITEM',
+    update: 'UPDATE_ITEM',
+    delete: 'DELETE_ITEM',
+    order: 'SET_ITEM_ORDER',
+  };
+
+  const state = {
+    'item-1': {
+      a: 1,
+      b: 2,
+    },
+    'item-2': {
+      c: 3,
+      d: 4,
+    },
+    order: ['item-1', 'item-2'],
+  };
+
+  describe('createTableReducer', () => {
+    it('should return a function', () => {
+      const reducer = createTableReducer(actionTypes);
+      expect(reducer).toBeInstanceOf(Function);
+    });
+  });
+
+  describe('created table reducer', () => {
+    it('initial state is object with empty "order" array', () => {
+      const reducer = createTableReducer(actionTypes);
+      const newState = reducer(undefined, {});
+      const expected = { order: [] };
+      expect(newState).toStrictEqual(expected);
+    });
+
+    it('returns unchanged state when action type is not supported', () => {
+      const reducer = createTableReducer(actionTypes);
+      const newState = reducer(state, { type: 'UNSUPPORTED_ACTION_TYPE_3E4F' });
+      expect(newState).toStrictEqual(state);
+    });
+
+    describe('handling of create action', () => {
+      it('should add action.payload to state. key should be taken from action.id.', () => {
+        const reducer = createTableReducer(actionTypes);
+        const payload = { bar: 77 };
+        const action = { type: actionTypes.create, id: 'item-3', payload };
+        const newState = reducer(state, action);
+        expect(newState['item-3']).toStrictEqual(payload);
+        // no changes in other items
+        expect(newState['item-1']).toStrictEqual(state['item-1']);
+        expect(newState['item-2']).toStrictEqual(state['item-2']);
+      });
+    });
+
+    describe('handling of update action', () => {
+      it('should update item by id. id is taken from action.id', () => {
+        const reducer = createTableReducer(actionTypes);
+        const payload = { a: 42, x: 66 };
+        const action = { type: actionTypes.update, id: 'item-1', payload };
+        const newState = reducer(state, action);
+        expect(newState['item-1']).toStrictEqual({ a: 42, b: 2, x: 66 });
+        // no changes in other items
+        expect(newState['item-2']).toStrictEqual(state['item-2']);
+      });
+
+      it('should not alter the state when payload is empy object', () => {
+        const reducer = createTableReducer(actionTypes);
+        const payload = {};
+        const action = { type: actionTypes.update, id: 'item-1', payload };
+        const newState = reducer(state, action);
+        expect(newState['item-1']).toStrictEqual(state['item-1']);
+        // no changes in other items
+        expect(newState['item-2']).toStrictEqual(state['item-2']);
+      });
+    });
+
+    describe('handling of delete action', () => {
+      it('should delete item from state. id is taken from action.id', () => {
+        const reducer = createTableReducer(actionTypes);
+        const action = { type: actionTypes.delete, id: 'item-1' };
+        const newState = reducer(state, action);
+        expect(newState['item-1']).toBeUndefined();
+        // no changes in other items
+        expect(newState['item-2']).toStrictEqual(state['item-2']);
+      });
+    });
+
+    describe('handling of order action', () => {
+      it('should set payload to "order" property', () => {
+        const reducer = createTableReducer(actionTypes);
+        const payload = [7, 6, 5, 4];
+        const action = { type: actionTypes.order, payload };
+        const newState = reducer(state, action);
+        expect(newState.order).toStrictEqual(payload);
+      });
+    });
+  });
+});
+
+describe('singelton reducer', () => {
+  const actionTypes = {
+    update: 'UPDATE_ITEM',
+  };
+
+  const state = {
+    a: 1,
+    b: [2, 3],
+    c: {
+      d: 4,
+      e: { f: 5 },
+    },
+  };
+
+  describe('createSingletonReducer', () => {
+    it('should return a function', () => {
+      const reducer = createSingletonReducer(actionTypes);
+      expect(reducer).toBeInstanceOf(Function);
+    });
+  });
+
+  describe('created singelton reducer', () => {
+    it('initial state is empty object', () => {
+      const reducer = createSingletonReducer(actionTypes);
+      const newState = reducer(undefined, {});
+      expect(newState).toStrictEqual({});
+    });
+
+    it('returns unchanged state when action type is not supported', () => {
+      const reducer = createSingletonReducer(actionTypes);
+      const newState = reducer(state, { type: 'UNSUPPORTED_ACTION_TYPE_3E4F' });
+      expect(newState).toStrictEqual(state);
+    });
+
+    describe('handling of update action', () => {
+      it('should update the state by deep merging payload object', () => {
+        const reducer = createSingletonReducer(actionTypes);
+        const payload = { a: 11, c: { e: { f: 55 } } };
+        const newState = reducer(state, { type: actionTypes.update, payload });
+        expect(newState).toStrictEqual({
+          a: 11,
+          b: [2, 3],
+          c: {
+            d: 4,
+            e: { f: 55 },
+          },
+        });
+      });
+    });
+  });
+});
diff --git a/src/state/reducers/createActions.js b/src/state/reducers/createActions.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae3969752a354f5369306f418bdec8aec07173e3
--- /dev/null
+++ b/src/state/reducers/createActions.js
@@ -0,0 +1,132 @@
+import uuid from 'uuid/v4';
+
+/**
+ * Create and return action creators for a table reducer.
+ *
+ * The `actionTypes` parameter is an object that maps from provided reducer actions
+ * to action type constants. Example:
+ *
+ *  {
+ *    create: 'CREATE_ITEM',
+ *    update: 'UPDATE_ITEM',
+ *    delete: 'DELETE_ITEM',
+ *    order: 'SET_ITEM_ORDER'
+ *  }
+ *
+ * The function names of the returned action creators are the camel-cased type constants.
+ * Given the above example, the function name for the delete action will be `deleteItem`.
+ *
+ * @param {Object} actionTypes
+ * @param {String} idPrefix - prefix for the item id in state
+ * @param {Object} defaultProps - default properties for an item. Used in the create action.
+ * @return {Object} - Object of actions creator functions.
+ */
+export function createTableReducerActions(actionTypes, idPrefix, defaultProps) {
+  /**
+  * Returns a create action for a table reducer.
+  *
+  * @param {Object} payload - Data that will be set to the item by the table reducer.
+  *   It gets shallow merged with the default properties and therefore may overrides the defaults.
+  * @param {String} id - Optional. Sets the item ID explicitly.
+  *   Otherwise the ID will be created automatically.
+  * @return {Object}
+  */
+  function createItem(payload, customId) {
+    const id = customId || `${idPrefix}-${uuid()}`;
+    return {
+      type: actionTypes.create,
+      id,
+      payload: { ...defaultProps, ...payload },
+    };
+  }
+
+  /**
+  * Returns an update action for a table reducer.
+  *
+  * @param {String} id - ID of item to be updated.
+  * @param {Object} payload - Update data.
+  *   It gets deep merged with the existing item data by the table reducer.
+  * @return {Object}
+  */
+  function updateItem(id, payload) {
+    return { type: actionTypes.update, id, payload };
+  }
+
+  /**
+  * Returns an delete action for a table reducer.
+  *
+  * @param {String} id - ID of item to be deleted.
+  * @return {Object}
+  */
+  function deleteItem(id) {
+    return { type: actionTypes.delete, id };
+  }
+
+  /**
+  * Returns an order action for a table reducer.
+  *
+  * The `order` property exists in the state of the reducer.
+  * It can be used to indicate the item order.
+  *
+  * @param {Array} payload - An array of IDs that will be set to the `order` property.
+  * @return {Object}
+  */
+  function setItemOrder(payload) {
+    return { type: actionTypes.order, payload };
+  }
+
+  return {
+    [toCamelCase(actionTypes.create)]: createItem,
+    [toCamelCase(actionTypes.update)]: updateItem,
+    [toCamelCase(actionTypes.delete)]: deleteItem,
+    [toCamelCase(actionTypes.order)]: setItemOrder,
+  };
+}
+
+/**
+ * Create and return action creators for a singleton reducer.
+ *
+ * The `actionTypes` parameter is an object that maps from provided reducer actions
+ * to action type constants. Example:
+ *
+ *  {
+ *    update: 'UPDATE_ITEM',
+ *  }
+ *
+ * The function names of the returned action creators are the camel-cased type constants.
+ * Given the above example, the function name for the update action will be `updateItem`.
+ *
+ * @param {Object} actionTypes
+ * @return {Object} - Object of actions creator functions.
+ */
+export function createSingletonReducerActions(actionTypes) {
+  /**
+  * Returns an update action for a singleton reducer.
+  *
+  * @param {payload}- Update data.
+  *   It gets deep merged with the existing item data by the singleton reducer.
+  */
+  function updateItem(payload) {
+    return { type: actionTypes.update, payload };
+  }
+
+  return {
+    [toCamelCase(actionTypes.update)]: updateItem,
+  };
+}
+
+/**
+* Translates an action type constant to a function name.
+*
+* E.g.: UPDATE_ITEM --> updateItem
+*
+* @param {String} constant
+* @return {String}
+*/
+function toCamelCase(constant) {
+  return constant
+    .split('_')
+    .map(word => word.toLowerCase())
+    .map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1)))
+    .join('');
+}
diff --git a/src/state/reducers/createReducers.js b/src/state/reducers/createReducers.js
new file mode 100644
index 0000000000000000000000000000000000000000..f42e980e84e89ff0eff836336df5b5bd6e611b51
--- /dev/null
+++ b/src/state/reducers/createReducers.js
@@ -0,0 +1,73 @@
+import deepmerge from 'deepmerge';
+
+/**
+ * Create a table reducer.
+ *
+ * A table reducer is a reducer that treats its data as a database-like table
+ * where each table consists of rows that have fields and each row has an ID.
+ *
+ * The `actionTypes` parameter is an object that maps from provided reducer actions
+ * to action type constants. Example:
+ *
+ *  {
+ *    create: 'CREATE_ITEM',
+ *    update: 'UPDATE_ITEM',
+ *    delete: 'DELETE_ITEM',
+ *    order: 'SET_ITEM_ORDER'
+ *  }
+ *
+ * @param {Object} actionTypes
+ * @return {Function}
+ */
+export function createTableReducer(actionTypes) {
+  return function tableReducer(state = { order: [] }, action) {
+    switch (action.type) {
+      case actionTypes.create:
+        return { ...state, [action.id]: action.payload };
+
+      case actionTypes.update:
+        return { ...state, [action.id]: deepmerge(state[action.id], action.payload) };
+
+      case actionTypes.delete:
+        return Object.keys(state).reduce((object, key) => {
+          if (key !== action.id) {
+            object[key] = state[key]; // eslint-disable-line no-param-reassign
+          }
+          return object;
+        }, {});
+
+      case actionTypes.order:
+        return { ...state, order: action.payload };
+
+      default:
+        return state;
+    }
+  };
+}
+
+/**
+ * Create a singleton reducer.
+ *
+ * In contrast to a table reducer (see above), a singleton reducer is a reducer
+ * that treats its data as a plain javascript object with no further constraints
+ * on the object structure.
+ *
+ * The `actionTypes` parameter is an object that maps from provided reducer actions
+ * to action type constants. Example:
+ *
+ *  {
+ *    update: 'UPDATE_ITEM',
+ *  }
+ * @param {Object} actionTypes
+ * @return {Function}
+ */
+export function createSingletonReducer(actionTypes) {
+  return function singletonReducer(state = {}, action) {
+    switch (action.type) {
+      case actionTypes.update:
+        return deepmerge(state, action.payload);
+      default:
+        return state;
+    }
+  };
+}