93

I have backend based on express + mongoose. File structure is:

- /models
-- item.js
- /node.modules
-- ...
- server.js
- package-lock.json
- package.json

And regular create-react-app based folder for front-end:

- /src
-- /assets
--- index.css
-- /components
--- Somecomponent.js
-- /containers
--- App.js
-- /reducers
--- somereducers.js
- /node.modules
-- ...
-- index.js
-- registerServiceWorker.js
- .gitignore
- package-lock.json
- package.json

I want to use it in proper way together. I wanted to organise it this way:

- /client 
-- /src
...
-- index.js
-- registerServiceWorker.js
- .gitignore
- package-lock.json
- package.json

- /server
- /models
-- item.js
- /node.modules
-- ...
- server.js
- package-lock.json
- package.json

At this stage I stuck. I can make it if client folder inside server folder or if server folder inside client. 1. But how to make it run when two folders are siblings? 2. What should be package.json and where node.modules should be (whether both server and client should have it's own package.json and modules?)

Angelzzz
  • 1,356
  • 2
  • 10
  • 20

3 Answers3

225

The most basic structure would be to have a root folder that contains frontend and backend folders. Since you're talking about the MERN stack, you would have a package.json inside of your NodeJS backend environment and a package.json for your React side of things. Backend server and the frontend client are two totally separate things, so yes, they both have their own node_modules folders. On the backend, you'll probably have installed something like Express for your Node runtime, Mongoose for a more convenient way to talk to your MongoDB, etc, and on your frontend, you'll have your React as your frontend framework, Redux for state management, etc. Additionally, depending on what you have already listed inside of your package.json files, when you run npm install separately it will be installed in those two folders. If you want to install additional packages, just run npm install + "the name of the package" (without the '+' and without the quotes) inside of that particular folder where you need it (backend or/ and frontend).

I hope this was helpful. Check out the pics, especially the 2nd one.

App structure
enter image description here

Folder structure

enter image description here

UPDATE:

In development, I suggest installing two additional things:

  1. npm i -D nodemon
  2. npm i -D concurrently

Note: The -D flag will install them as devDependencies.

nodemon is going to track every file change and restart the backend server for you. So, it's obvious that it should be installed inside of the "backend" folder. All you have to do is go inside of the package.json file (backend) and add a new script. Something like this:

"scripts": {
"start": "node app.js",  // in production
"dev": "nodemon app.js", // in development
}

concurrently allows you to start both your frontend and backend at the same time. I suggest initializing a new Node project inside of the top-level root folder -[folder which contains both, your frontend and backend]. You would do that with the npm init command, and after that, install the concurrently package there.

Now, go open your newly created package.json file inside of your root folder and edit the start section, like this:

   "scripts": {
       "dev": "concurrently \"cd backend && npm run dev\" \"cd frontend && npm start\" "
   }

What this will do is go inside of the backend folder and run the dev command (the same one we just configured), so that will start nodemon. Additionally, it will also go inside of the frontend folder and run the default start command -which is exactly what we want.

If you kept the folder structure, installed all the dependencies (including the additional two I mentioned above), changed the package.json file inside of your root folder, you'll be able to start them both with a simple command:

npm run dev // make sure you're inside of the root folder when doing so :)

Dženis H.
  • 7,284
  • 3
  • 25
  • 44
  • 13
    That's was very helpful. How to run both backend and frontend with one `npm start` command? – Angelzzz Jul 02 '18 at 06:19
  • 3
    Sure, I'll update my previous answer with that info, and if that's helpful too, please accept my answer ;) – Dženis H. Jul 02 '18 at 12:35
  • 1
    Completely off topic, but what IDE/theme is that folder structure screenshot? – Icode4food Oct 17 '18 at 02:29
  • 2
    @Icode4food Editor: **VS Code** with a **Custome theme** (meaning I made it myself changing the user preferences). You can do it also by hitting **CTRL + P**, in the search box enter `> Preferences: Open user settings` and edit the `editor.tokenColorCustomizations, workbench.colorCustomizations` and everything else you might want to customize to fit your needs. I have a lot of it :) ... and btw for the icons, I'm using the **material-icon-theme**. If you want to avoid all that I suggest, installing a theme called **One Dark Pro Monokai Darker**. It's kinda similar to what I got. Cheers **;)** – Dženis H. Oct 17 '18 at 15:15
  • 1
    Thank you for this answer! I work in Vue, but it looks like the architecture will translate. – Len Joseph Mar 04 '19 at 03:31
  • 3
    @I'mOnlyVueman The pleasure is all mine. Trust me. By the end of the day, it's all `JavaScript`, right? -So, it doesn't really matter is it React, Angular or Vue It's all about the architecture and scalability. Have a good one ;) – Dženis H. Mar 04 '19 at 09:37
  • 6
    @Bigga_HD, would you recommend having the root folder uploaded to a single GitHub repo or two separate ones? – Otto Gutierrez Jul 25 '19 at 02:38
  • 4
    Definitely one repo. Good luck ;) @Otto Gutierrez – Dženis H. Jul 31 '19 at 19:57
  • I'm really new to MERN. Could you please tell me how would the backend interact with the built files in the frontend folder? Or does it do something else? – Sapinder Singh Sep 29 '20 at 07:18
  • 2
    @Sapinder You can either run them separately or you could copy the [build files](https://create-react-app.dev/docs/deployment/) to a folder on the server (e.g. 'public') which you would then expose via the [static method](https://expressjs.com/en/starter/static-files.html). There's also [SSR](https://reactjs.org/docs/react-dom-server.html), but it is a bit more advanced topic. I would go for the second option. So, there's your answer `How do they interact?` -> By sending the appropriate HTTP request from the client to the appropriate endpoint on the server and vice versa. – Dženis H. Oct 04 '20 at 16:08
  • 1
    @DzenisH. Your answer helped me a lot. I have 1 question, instead of using concurrently in the `package.json` at root directory, I simply used the script: `"install": "(cd backend && npm install) & (cd frontend && npm install)"`. So it this also acceptable or can there be some potential issues with it ? I have similar script for running: `"dev": "(cd backend && npm run start) & (cd frontend && npm run start)"` – Harshit Trehan Dec 15 '20 at 12:16
  • 2
    @HarshitTrehan That's fine, I guess. However, it can get hard to keep track of different outputs. Additionally, if one process fails (for whatever reason), others still keep running, and you won't even notice the difference (until it's too late and you're pissed) :) That's just my two cents. Anyways, keep up the good work, and I'm thrilled that my answer was helpful. Cheers. – Dženis H. Dec 15 '20 at 14:11
  • 1
    Oh yeah. I didn't think of that scenario. I already had quite a lot of dependencies for my MERN project so I figured maybe not to use concurrently, but since its just a dev dependency I guess its okay. Thanks again. Cheers :) – Harshit Trehan Dec 15 '20 at 14:44
  • This works well in development. But how do you deploy a mern stack app with such a file structure to a platform like digital ocean where am using the digital ocean new app platform? – Dijiflex Jun 24 '21 at 09:33
  • @Dijiflex The question is not about deployment. There's not a single mention of it in the original question. There are many different ways to deploy a MERN app. May I suggest posting a SO question and linking it to a comment below? Have a good one. – Dženis H. Jun 24 '21 at 21:14
  • very insightful, In my case .gitignore exist on root level of backend, I will be dragging a react them in, do I have to keep another .gitignore in `client`aka `frontend` folder ? or uses same root level .gitingore for both – Muhammad Uzair May 25 '22 at 12:54
  • @MuhammadUzair It all depends how you want to push your code. If you want to push it all (backend and fronted) then have a single. gitignore file at the root level, but if you want to separate FE from BE you would have 2 of those files, on for FE and another one for BE. – Dženis H. Jun 15 '22 at 22:55
  • So how do you deploy this so that Express serves the React frontend? Do you use `../../` in the path to get to the sibling folder? – Florian Walther Jan 15 '23 at 15:41
  • @FlorianWalther No, you deploy the FE from the BE separately – Dženis H. Mar 25 '23 at 07:16
26

Adding to the accepted answer, the folder structure division inside the frontend and backend is more useful if it is based on business logic rather than tech logic.

Dividing the whole stack into self-contained components that preferably don't share files among them is the best way to make your app more testable and easy to update. This in the smallest possible way is what commonly known as microservice architecture.

Bad Design : difficult to update and test:
Bad Design for folder structure

Good Design : easy to update and test:

Good Design for folder structure

Saurabh Ariyan
  • 827
  • 11
  • 21
  • 2
    This answer interests me, but I feel that it lacks justification. Could you explain it a little better for a newbie like me? – GermanJablo Jun 23 '21 at 07:59
  • 4
    This is kind of based on django file structure which i have found easier to test and update. Each bussiness component is one "app". Seperating based on bussiness logic rather than keeping same type (classes) together is easier to maintian in a larger team, imho. Refactoring becomes easier, seperation of concerns is more clearly defined and domain boundaries are more clearly defined. – Saurabh Ariyan Jun 25 '21 at 23:40
  • I'm actually interested about this answer too. I've learned to do it the "bad way" but now seeing your answer I like your suggestion a lot. My question is: You mention that is somehow used in microservices architecture? Do you have some reference where we can read fruther? Tahnks! – NordinZ Jan 31 '23 at 07:16
  • 1
    Rarely in my career have I ever found a business domain with this kind of clear separation. Do you duplicate the product.js in the orders folder? Leave out FK in data structure between products and orders? If not, it's not a microservice, though many companies call it that and then struggle to figure out why they're having so much trouble. And, I would expect my junior developers to be regularly referencing "layers" incorrectly if I structured my team's code this way. I were the only coder and I didn't expect anyone else to support it, I might consider this approach. – EGP Feb 26 '23 at 04:56
0

Use Structure as per your requirement, like based on the project scope or depth. But make sure to keep the endpoints and models separate, so initially have a setup like such

src/
controllers - for the endpoints
models - for the schema
server.js - or index.js
SantyNaren
  • 11
  • 1