How I Organize React Projects
Tags: react, javascript, typescript, tutorial
Published: 2020-08-26 03:34:23

I fully understand that talking about the "right" way to organize a React project (or, a project using _any_ framework in _any_ language) is a bit like talking about the "right" way to style your hair.  (Although I think we can all agree that the objectively "right" way to style your hair is, quite obviously, in a Mohawk.)

As "basic" as project layout can be, I still find myself - after a quarter century in this game - constantly tweaking and evolving my "default" project structure.  So before I dive into more tactical details of my Spotify Toolz project (https://www.spotifytoolz.com), I wanted to crank out a quick article about how I _currently_ organize my React projects. 

I also welcome some "audience participation" on this article.  Even now, after all this time slinging code, it seems that every six-months-or-so, I come to some stunning realization that "_this_ data should really be stored over _there_!"  So I'd love to see _your_ best practices for how to organize projects. 

As with all issues as subjective as "project organization", I can 100% guarantee that my _current_ approach is the empirically best approach.  I can also guarantee that any other approach is "wrong".  And that, six months from now, I will have adopted an entirely different approach to project organization.  At that time, I'll scoff at anyone who follows the organization in _this_ article and I'll dismissively tell them that I've moved on to a far superior organization scheme.

If you use this organization scheme, and you eventually grow unsatisfied with it, I will gleefully offer to refund 150% of the money that you paid to read this article.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9hg4x8uho6voxr7ugrr5.jpg)
## Basic Organization
(If you can't fathom what the above image represents, I will try to forgive you.  Suffice it so say that it's something akin to a phonograph, or a buggy whip.)

Most of my (latest) React projects have a structure pretty close to this:

```javascript
/src
  app.js
  /shared
    /classes
    /components
    /css
    /functions
    /hooks
    /objects
      /models
  /routes
```

If there is any UI aspect to my app at all, I usually assume that I'll be using React Router.  And if I'm using React Router, then the `/routes` directory becomes a one-to-one representation of the (faux) directories that the user sees as they navigate through the app.  

So, if the app has a `users` module (`/user`), which then has separate "pages" to create (`/user-create`), edit (`/user-edit`), and view (`/user-view`) a user, my project would look like this:

```javascript
/src
  app.js
  /shared
    /classes
    /components
    /css
    /functions
    /hooks
    /objects
      /models
  /routes
    /user
      /create
      /edit
      /view
```

Furthermore, when I create components that map to these routes, they're represented by JS files under their appropriate folders.  So, once we fill in the base components for each route, the tree looks like this:

```javascript
/src
  app.js
  /shared
    /classes
    /components
    /css
    /functions
    /hooks
    /objects
      /models
  /routes
    /user
      /create
        /components
          create.user.js
      /edit
        /components
          edit.user.js
      /view
        /components
          view.user.js
```

Notice that there are no files _directly_ under the `/routes/{routeName}` folders.  This is because _everything_ that defines a route should logically fall under either the `classes`, `components`, `css`, `functions`, `hooks`, or `objects` folders.  

On a practical level, this means that _most_ of the logic for my routes are located under `/src/routes/{routeName}/components/{route.name.js}`.  Because, for most of my routes, all of the route-specific logic is encapsulated in `/src/routes/{routeName}/components/{route.name.js}`.

Now let's imagine that `view.user.js` (which will be the `<ViewUser>` component) requires a function that is called `getLastUserLoginTimestamp()`.  When I create that function, I have an organizational choice to make.  The choice is determined by this question:
<br/>

> Will this function be used in _this_ component, and _only ever_ in this component??

<br/>If this answer is "yes" (i.e., if this function is _completely unique and solely targeted_ to this component), then I would create a structure that looks like this:

```javascript
/src
  app.js
  /shared
    /classes
    /components
    /css
    /functions
    /hooks
    /objects
      /models
  /routes
    /user
      /create
        /components
          create.user.js
      /edit
        /components
          edit.user.js
      /view
        /components
          view.user.js
        /functions
          get.last.user.login.timestamp.js
```

In this scenario, I've decided that the `getLastUserLoginTimestamp()` function will only ever be used in the `ViewUser` component.  For that reason, I created a separate `/functions` directory under the `/src/routes/user/view` directory.  The implication is that `getLastLoginTimestamp()` will _only_ ever be used inside the `ViewUser` component.  And thus, the `/functions` directory that houses the function should only ever live under `/src/routes/user/view`.

But to be frank, the above example is rare.  Typically, when I'm creating helper functions, I already know they'll be used in other places throughout the app.  In fact, even if I'm not sure how they will be used throughout the app, I usually assume that the functions I'm creating will, eventually, be used in other places.  

For this reason, I rarely house the functions under a specific `/src/routes/{routeName}` directory.  More often than not, I house those functions under the `/shared` directory.  So that would look like this:

```javascript
/src
  app.js
  /shared
    /classes
    /components
    /css
    /functions
      get.last.user.login.timestamp.js
    /hooks
    /objects
      /models
  /routes
    /user
      /create
        /components
          create.user.js
      /edit
        /components
          edit.user.js
      /view
        /components
          view.user.js
```


<br/><br/>![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sgs7oy31oob3z2n0ueos.jpg)
## Sharing Is Caring
If it's not clear already, the '/src/shared' directory in my apps houses the lion's share of all my application logic.  This happens for two reasons:
<br/>

1. Many classes / components / styles / functions / hooks / objects are designed, from the very start, to be "universal".  Even if I don't _know_ how a particular file will be re-used in the future, I'm typically writing my files in such a way that I _assume_ they'll be re-used.  And thus, most of those files end up being housed under `/src/shared`.<br/><br/>

1. Even if it seems like a given class / component / style / function / hook / object will only ever be used in a single route, I tend to save the file under `/src/shared` unless I'm _absolutely 100% certain_ that the file will never possibly be used anywhere else.<br/><br/>

This tends to mean that my `/src/shared` directory is an ever-growing library of potentially-reusable assets.  It also means that my `/src/routes` directories are sparse - but they are a fairly simple one-to-one mapping of the user's potential paths through the application.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9i0opv6fp3k12hpvif2d.jpg)
## Important Notes
At this point, I typically write _all_ of my React components as _function-based_ components.  This means that I don't use `export class SomeComponent extends React.Component {...}`.  Instead, I write `export const SomeComponent = () => {...}`.

So when you look at the directory structure above and you see `/src/shared/classes`, it might be tempting to think that this directory houses class-based _components_.  But that's not the case.

In my chosen project structure, `/src/shared/classes` only houses _utility_ helper classes.  For example, I frequently use a helper class for `localStorage` (that you can read about here: https://dev.to/bytebodger/getting-more-out-of-and-into-storage-with-javascript-41li) and a validation library (that you can read about here: https://dev.to/bytebodger/better-typescript-with-javascript-4ke5).  This is my only real use of _classes_ in my most-recent React development.

You'll notice that, under `/src/shared`, there's a `/components` directory.  This isn't for the "main" components that define routes.  This is for all of those "helper" components (e.g., Higher Order Components) that I end up using repeatedly throughout my app.

In my particular approach, the `/src/shared/css` folder typically houses actual CSS classes.  If I'm using inline-CSS within my JSX, that's defined in `/src/shared/objects`  (because, with inline CSS, styles _are_ JavaScript objects).

I rarely ever create a Hook that does _not_ live under `/src/shared/hooks`.  In my way of thinking, if your Hook will never be shared between multiple components, then why wouldn't you just define it in the body of the single functional component where it's used??

Finally, my use of `/src/objects` may be confusing to some.  I've found a number of use-cases for "plain ol JS objects" in my dev.  You can find one example of that here:  https://dev.to/bytebodger/hacking-react-hooks-shared-global-state-553b and here: https://dev.to/bytebodger/why-is-this-an-anti-pattern-in-react-427p

As for my use of `/src/objects/models`, that's explained with my validation library here: https://dev.to/bytebodger/better-typescript-with-javascript-4ke5 In brief, my `/src/objects/models` helps me to validate the _shape_ of objects that are being passed into my functions.
<br/><br/>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/75upytb4n77wm2nkheom.jpeg)
## Show Me Yours
This is how I currently organize React projects.  (Which I'm sure we'll all agree is the _right_ way.)  How do you organize _your_ projects?  Have I overlooked anything???  Lemme know...