What is Redux Ducks?

Matthew Holman
2 min readJun 8, 2018


I was in the process of implementing Redux on a large React SPA at work. I had already setup the file structure as I had seen and used before on smaller applications. However, I began to wonder if my setup would scale well as the application grew. A colleague suggested I look into ‘Redux Ducks’. I thought ‘That’s a silly name…’ and started to do some research. Below is a synopsis of my research:

Ducks is a modular pattern that collocates actions, action types and reducers.

According to the Ducks proposal:

A module…

1. MUST export default a function called reducer()

2. MUST export its action creators as functions

3. MUST have action types in the form npm-module-or-app/reducer/ACTION_TYPE

4. MAY export its action types as UPPER_SNAKE_CASE, if an external reducer needs to listen for them, or if it is a published reusable library

Getting your ducks in a row…

Modular? Working with React, I love modular. But, what does a real module look like? Well, here’s an example straight from the Ducks proposal:

// Actions
const LOAD = 'my-app/widgets/LOAD';
const CREATE = 'my-app/widgets/CREATE';
const UPDATE = 'my-app/widgets/UPDATE';
const REMOVE = 'my-app/widgets/REMOVE';

// Reducer
export default function reducer(state = {}, action = {}) {
switch (action.type) {
// do reducer stuff
default: return state;

// Action Creators
export function loadWidgets() {
return { type: LOAD };

export function createWidget(widget) {
return { type: CREATE, widget };

export function updateWidget(widget) {
return { type: UPDATE, widget };

export function removeWidget(widget) {
return { type: REMOVE, widget };

// side effects, only as applicable
// e.g. thunks, epics, etc
export function getWidget () {
return dispatch => get('/widget').then(widget => dispatch(updateWidget(widget)))

Finally, here is a trivial ToDo app example on GitHub, created by Cody Barrus.

We did not end up using the Redux Ducks pattern in our codebase, but I will explain my experiences using Ducks and the implementation we ended up using in another article.