All Articles

A “Composable” React/Redux File Structure?

Even though users don’t care about your file structure and a correct one doesn’t exist, I’ve a habit of experimenting with them in my React/Redux applications.

The two most popular I’ve tried are by nature and by domain.

By nature

/src
  /components
  /reducers
  /actions
  /containers

By domain

/src
  /feature1
    component.js
    reducer.js
    actions.js
    container.js

  /feature2
    component.js
    reducer.js
    actions.js
    container.js

“By nature” is perfect for smaller apps and beginners learning React/Redux. Everything is self-explanatory and sits with its own kind.

“By domain” makes larger apps easier to think about as everything’s broken up by what it does, not what it is.

I love them both, but feel something’s missing. Neither lend themselves well to the mantra, “composition over inheritance”. I don’t feel like my features are compositions of many components, reducers, and actions.

So what if we fused these two popular paradigms?

A Composable, Hybrid Structure

/src
  /features
    /feature1
      index.js
      component.js
      duck.js

  /components
  /ducks

I believe this hybrid nicely supports apps that emphasize composition.

Key points:

  • /components contains HoCs (higher-order components) and other simple components. These are your building blocks.
  • /ducks is like /components, except with higher-order ducks (reducers/actions). Implements Erik Rasmussen’s “Ducks” proposal.
  • feature/index.js is the Redux-connected container, composed of building blocks from /components.
  • feature/component.js is the stateless, presentational component also composed from /components.
  • feature/duck.js is composed from /ducks and is used in your Redux store.

I purposely excluded the router, store, root reducer and unit tests because that’s all subjective.

The main point is to think about your features as composing a bunch of components, reducers, and actions, which are all just functions.