How to Setup and Deploy a MERN stack project for FREE 🌐🚀
Tags: react, node, beginners, tutorial
Published: 2023-03-19 14:52:52

{%youtube ScVd8Pr80aA %}
## Introduction:
If you're a developer who's just starting out with the MERN stack, you may be wondering how to deploy your project for the world to see. Luckily, there are free options out there, and in this article, we'll walk you through the process of setting up and deploying a MERN stack project using **[Render.com](https://render.com)**

Now, let's get started with setting up our MERN stack project!

## Root Folder
The first step is to create a root folder for the project, you can name the folder anything you want, I will name the root folder **mern-deploy**.

## Setting-up Backend
Open any code editor inside the root folder (I am using VS Code), and then create a folder named **backend**. After this, Open the terminal by pressing **CTRL + `` ` ``** If you are on windows. I don't know about MacOS 😅.
Run this command:
```shell
cd backend
```
Now you will be inside the **backend** folder.
Run this command to install all the required dependencies.
```shell
npm install express mongoose dotenv cors
```
Create a file named **.env** to store all your secret keys.
Our **.env** file should look something like this:
```javascript
MONGODB_URI=YOUR_MONGODB_URI
PORT=4000
```
Now, create a file named **app.js**, and write some code inside it.
### app.js
```javascript
const express = require("express");
const mongoose = require("mongoose");
const app = express();
const cors = require("cors");
require("dotenv").config();

// middleware
const corsOptions = {
    origin: "http://localhost:3000" // frontend URI (ReactJS)
}
app.use(express.json());
app.use(cors(corsOptions));

// connect MongoDB
mongoose.connect(process.env.MONGODB_URI).then(() => {
    const PORT = process.env.PORT || 8000
    app.listen(PORT, () => {
        console.log(`App is Listening on PORT ${PORT}`);
    })
}).catch(err => {
    console.log(err);
});

// route
app.get("/", (req, res) => {
    res.status(201).json({message: "Connected to Backend!"});
});
```
Note that you'll need a MongoDB database URI. If you don't already have a MongoDB database, you can create one for free on **[MongoDB](https://mongodb.com)**. Once you've created a project and a database, you can generate a database URI and add that URI inside the **.env** file.

After following these steps, you should have a basic backend server set up with a single home route. In the next step, we'll set up the frontend of our MERN stack project.

## Setting-up Frontend
Now, open the terminal and run this command to go back to the root folder.
```shell
cd ..
```
Inside the root folder, run this command to initialze ReactJS boilerplate.
```shell
npx create-react-app client
```
Once this is done, delete all the unnecessary boilerplate files, and inside the **App.js** file make a fetch request to the backend to show the message.
### App.js
```react
import { useEffect, useState } from "react";

function App() {
  const [message, setMessage] = useState("");

  // Fetching message from backend on mount
  useEffect(() => {
    fetch("http://localhost:4000")
      .then((res) => res.json())
      .then((data) => setMessage(data.message));
  }, []);

  return (
    <div className="App">
      <h1>{message}</h1>
    </div>
  );
}

export default App;
```

## Deleting **.git** folder inside client
Delete the **.git** folder inside the **client** folder to prevent any conflicts during the deployment process. I would recommend you to delete it manually using the file manager. Also delete the **.gitignore** file.

## Setting-up Root folder for Deployment
Now we have everything set for backend and frontend, let's create package.json file for the root folder by running this following command:
```shell
npm init -y
```
It will generate a package.json file with default fields.
### package.json
```javascript
{
  "name": "mern-deploy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```
Now we need to have **.gitignore** file, so that when we push our code to github all the mentioned files & folders inside will be ignored. So, create a **.gitignore** file and add all these.
### .gitignore
```shell
# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# production
build

# misc
.env
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
```
Now, we need to add some scripts to our **package.json** file to help us start our project and build it for deployment. Add the following scripts to your root folder's package.json file:
```javascript
{
  "name": "mern-deploy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "install-server": "cd backend && npm install",
    "start-server": "cd backend && node app.js",
    "install-client": "cd client && npm install",
    "build-client": "cd client && npm run build",
    "start-client": "cd client && npm run start"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```
These scripts allow us to install our server and client dependencies, start our server and client separately, and build our client for deployment.

## Creating GitHub Repository
After adding the necessary scripts to your package.json file, the next important step is to host your code on a version control platform like GitHub.
So, create a new repository on **[github.com](https://github.com)** and then follow this steps on your terminal:
- Add all the files to the staging area using the command **`git add .`**
- Commit the changes using the command **`git commit -m "initial commit"`**
- Add your GitHub repository as a remote using the command **`git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY_NAME.git`**. Make sure to replace "YOUR_USERNAME" and "YOUR_REPOSITORY_NAME" with your actual GitHub username and repository name.
- Rename master branch to main branch using **`git branch -M main`**
- Push your code to the repository using the command **`git push -u origin main`**.

## Deploy to Render.com
Now that your project is hosted on GitHub, you can deploy it to Render.com. Here's how to do it:
- Create an account on **[Render.com](https://render.com)** if you haven't already.
- Link your GitHub account to give access to your repository.
- Click on "New" and select "Web Service" from the option.

![New Project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7g2splwuew8kh2vj9mmg.png)

![Web Service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72ize1mywrlugs3h09hk.png)
- Select your repository, and in the next screen, fill the fields as shown below:

Name: **YOUR_DESIRED_NAME**
Runtime: **Node**
Build Command: **npm run install-server**
Start Command: **npm run start-server**

![Settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfip6rbe9xsuj0wczbul.png)
- Open Advanced option, and add environment variables.

![Environment Variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onahkaelvni9ngbyw5sc.PNG)
- Click on "Create Web Service" to deploy your backend.

![Create web service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73wcdqpo70l81qy7ttqn.PNG)

## Add Backend URL to Frontend
Once the backend is successfully deployed, copy its URL and add it to the client/**App.js** file.
### App.js
```react
import { useEffect, useState } from "react";

function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    fetch("https://YOUR_BACKEND_URL.com")
      .then((res) => res.json())
      .then((data) => setMessage(data.message));
  },[]);

  return (
  <div className="App">
    <h1>{message}</h1>
  </div>
  );
}

export default App;
```
Again, stage and commit the changes to GitHub.

## Deploy Frontend
Now the backend is ready, its time to deploy our frontend to render.com
Here's how to do it:
- Click on "New" and select "Static Site" from the option.
- Select your repository, and in the next screen, fill the fields as shown below:

Name: **YOUR_DESIRED_NAME**
Runtime: **Node**
Build Command: **npm run install-client && npm run build-client**
Publish directory: **./client/build**

![frontend settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k31qfzqg5miawj7javop.PNG)
- Click "Create Static Site" to deploy your frontend.

## Add Frontend URL to Backend
Once the frontend is successfully deployed, copy its URL and add it to the backend/**app.js** file.
### app.js
```javascript
const express = require("express");
const mongoose = require("mongoose");
const app = express();
const cors = require("cors");
require("dotenv").config();

// middleware
const corsOptions = {
    origin: "YOUR_FRONTEND_URL", // frontend URI (ReactJS)
}
app.use(express.json());
app.use(cors(corsOptions));

// connect MongoDB
mongoose.connect(process.env.MONGODB_URI).then(() => {
    const PORT = process.env.PORT || 8000
    app.listen(PORT, () => {
        console.log(`App is Listening on PORT ${PORT}`);
    })
}).catch(err => {
    console.log(err);
});

// route
app.get("/", (req, res) => {
    res.status(201).json({message: "Connected to Backend!"});
});
```
Again, stage and commit the changes to GitHub.

And that's it! Your MERN stack project should now be up and running on Render.com

Thanks for Reading! ❤