The Three Pigs: how to structure your React-Redux application

Kadi Kraman
Frontend Weekly
Published in
3 min readMar 22, 2017

Defining any kind of “good practices” in tech is always a tricky business. Good practices are subjective, heavily dependent to your ways of working and often your personal preference. The best we can do is rely on the experience of others and learn from their mistakes.

Starting out with Redux can be quite daunting and figuring out the best way to group the bits and pieces of your application into a sensible folder structure can be tricky. Having been on three green-field React Redux projects in the last year, I have some musings to bestow, regarding the different approaches we’ve taken to end up with what is our “best shot so far”.

Similar to the three pigs building progressively sturdier houses, me and the teams I worked with gradually arrived at solutions providing better maintainability and a more efficient developer experience. From beginning with straw, progressing to wood and now iterating further with stone, here is my story.

The Straw House: Standard Layout

On the very first project, the whole team was new to Redux. And to be honest, Redux was new to the world (ride the wave!). We played it safe and went with a standard layout, as described in Dan Abramov’s amazing (and FREE) Egghead videos.

/src
/components
/containers
/actions
/reducers
/sagas

This is the obvious layout and the one that’s most people’s go-to: group the same ”type” of things together. It’s a brilliant starting point, but when working on large applications, it becomes pretty clear that this layout does not scale. Suppose we have a ToDo list application and consider the user adding a new ToDo item. You would probably have a ToDoItemList component, a ToDoItemList container, an ADD_TODO action, a todoItems reducer and if you need to make API calls to save your ToDos, a ToDoList saga. That’s an awful lot of files scattered about the codebase that are ultimately working on the same task. Besides, some things just belong together: you’d never use the ToDoItemList container with a different component so should they really be living in different parts of the codebase?

The Wooden House: Group by Feature

In the second project, having learned some good learnings from our straw house approach, we decided to do a 180: rather than separating all of our Redux bits based on what they do, we grouped them all together by the feature in which they belong. We also had a components folder for pure functional components that could be shared between different features.

/src
/components

/PureComponent1
index.js
index.spec.js
style.css
/PureComponent2
index.js
index.spec.js
style.css
/PureComponent3
/features
/feature1

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

This layout minimises jumping around in the codebase when developing features. It worked really well to begin with, however after a while it became clear that the lines between features are blurred. How do you draw the line between User, Account and Profile? Are they all the same feature? It is also easy to end up with just one or two bulky “features” that encompass the entire application.

The Stone House: Group by Function

The stone house layout basically appeared by letting the codebase grow naturally. From the start, we did the minimal possible amount of work ONLY for the feature at hand, refactored A LOT, took great care not to optimise too soon and added groupings and abstractions only when needed. We are now 4 months into the project and this is what we’ve come up with:

/src
/components
/Component1

index.js <— may be a pure component or a component wrapped in a container, the consumer doesn’t care anyway
index.spec.js
/Component2
/Component3

/reducers
index.js
/Reducer1
index.js <— actions are in the same file as reducers
index.spec.js
someSideEffect.js <— we use redux-loop here
/Reducer2
/Reducer3

Whereas this way of laying out the application may look a bit hard to grasp initially, it’s worked out really well for us so far. Grouping different “types” of files together isn’t a new idea. After all, in most React applications, test files and css files live in the directory of the component they belong to.

I am by no means finished evolving with the stone house and would love to hear about other ideas. If you have a different type of house (folder layout) than any of the ones listed here, let me know :)

Happy Reduxing!

--

--

Kadi Kraman
Frontend Weekly

Software engineer at @FormidableLabs. Building things in JavaScript. Fan of React, React Native, Node.js. Lover of board games. Glad to be Estonian 🇪🇪