Structuring a Complex React/Redux Project
Tags: react, redux, webdev, showdev
Published: 2018-03-08 00:29:39

---
title: Structuring a Complex React/Redux Project
published: true
tags: react,redux,webdev,showdev
canonical_url: https://www.nylas.com/blog/structuring-a-complex-react/redux-project
cover_image: https://www.nylas.com/hubfs/blog%20images/Dashboard%20Structure/blog_dashboard_structure_v1_2.28.png
---

The Nylas engineering team recently updated the [Nylas Dashboard](https://dev.to/nylas/announcing-the-nylas-dashboard-20-1pg-temp-slug-6941808), giving everyone on our customer's teams -- from developers to product managers, sales engineers, customer success reps and finance teams -- the ability to access their Nylas API account. 

After our [blog post about increasing developer speed](https://dev.to/nylas/raising-the-limits-on-developer-speed-4dgl) during the revamp of the Nylas Dashboard, we had some follow-up requests for a) the scaffold script we wrote, which is now available [here](https://gist.github.com/hallamoore/bf4e18e64cca1b9e45bf69901e56ee43), and b) the general structure of the project. 

Our dashboard front-end code is a React/Redux application, and the general structure looks something like this:

```javascript
src/
  appConstants/
  components/
    DropdownMenu/
      dropDownArrow.png
      index.js
      index.test.js
      stylesheet.js
    ...
  containers/
  higherOrderComponents/
  layouts/
  models/
  modules/
  screens/
  store/
    accounts/
      actions.js
      constants.js
      endpoints.js
      reducers.js
      selectors.js
    applications/
    ...
    actions.js
    api.js
    configureStore.js
    rootReducer.js
    selectors.js
  index.css
  index.js
  registerServiceWorker.js
  Routes.js
```

🙀 There’s a lot going on here, so I’ll briefly break down what each directory or file is for.

`appConstants/` is simply where we kept any application-wide constants, like API keys for third party services. We originally named this `constants/`, but it turned out that there was another constants node module elsewhere in the project that caused naming conflicts, so we renamed it to `appConstants/` instead.

We broke up our React components into multiple directories to try to keep things grouped in a more manageable manner. We initially only had a split between presentational components and containers. The important distinction between these is that presentational components are stateless while containers are not. You can learn more about the difference between presentational components and containers from [this article](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0). However, as we continued to add more and more components, we needed more separation. The directories we ended up with are:

- `components/` - the original directory for presentational components. Most of our presentational components still live here.
- `containers/` - the original directory for containers. (I bet you couldn’t have guessed that one 😜)
- `higherOrderComponents/` - [Higher Order Components (HOCs)](https://reactjs.org/docs/higher-order-components.html) are a special type of container that are actually functions. These functions encapsulate reusable logic patterns and are used to wrap other components with that logic. For instance, one of our HOCs is a LazyLoaded component. This displays a loading indicator before the necessary data is loaded, and reports back to us if it takes too long. We pass any screens that need this loading behavior through the LazyLoaded HOC rather than having to re-implement the behavior within each one! 💥
- `layouts/` - This is the only other directory that holds presentational components. These presentational components are specifically concerned with how an entire page in our application is laid out.
- `screens/` - Screens are containers that pull in all of the presentational components and sub-containers for a particular application view. All of our screens start with a layout component and add children from there.

Each component has its own subdirectory within one of those parent directories. The main file in each subdirectory is `index.js`, which is where the general component definition goes. `index.test.js` is the test file that we automatically add via our scaffolding script. We also keep any styling for the component in this subdirectory. This includes any images it needs and a separate `stylesheet.js` file if the styles get too bulky to keep in `index.js`. We used [Aphrodite](https://github.com/Khan/aphrodite) to be able to write our styles in JavaScript, which helped us keep the styles localized to each component rather than buried in massive CSS files.

`/models` is where we defined classes for each of our API objects. Each class defined a `toJSON()` and a `fromJSON()` method which allowed us to transform JSON responses into instances while we worked with them inside the application, and then back to JSON when we had to send the data back to our servers. The project also uses [Flow](https://flow.org/) as a type checker, and transforming the JSON into more concrete data structures allowed us to properly type-annotate each field.

`/modules` is basically a directory for utility or helper code. We grouped closely-related code into their own files and ended up with modules like `errorReporter.js` and `apiRequest.js`.

`store/` is for all of our Redux code. As I mentioned in my previous blog post, we separated our store into subdirectories for each of our models. Each of these subdirectories had the traditional Redux files of `actions.js`, `reducers.js`, and `selectors.js`. We additionally had a `constants.js` file for any constants relevant to that model store, and `endpoints.js` for functions that interact with our back-end API. At the `store/` root, we have files that import all of the functions from the corresponding subdirectory files:

- `actions.js` imports from all of the sub `actions.js` files
- `api.js` imports from all of the sub `endpoints.js` files
- `rootReducer.js` combines all of the sub `reducers.js` files
- `selectors.js` imports all of the sub `selectors.js` files

We also have `configureStore.js` which does the initial setup of actually creating the store and potentially loading any previously saved state. 

`index.css` holds our over-arching CSS styles. Most of our styles are inside our component directories, but there are a few `body` and `html` level styles that live in this file instead.

`index.js` simply renders our root React component.

`registerServiceWorker.js` sets up service workers so that we can serve assets from a local cache to make our application run faster.

`Routes.js` connects each of our screen components to an application route. For example, this is where we register our `RegisterScreen` to be loaded when the user visits the `/register` route in our dashboard.

Overall, we tried to structure our project such that all of the relevant code is nearby when we’re working on a specific part, while still maintaining a separation of concerns. Keeping smaller files grouped by model or component really helped improve the developer experience. We may continue to iterate on our structure in the future, but so far this has worked well for us! Let us know if you have any questions or if you do things differently at your company.

----

This post was originally published on the [Nylas Engineering Blog](https://www.nylas.com/blog/structuring-a-complex-react-redux-project)