Building a Full-Stack Web Application with MERN Stack: A Beginner's Guide
Tags: mernstack, react, mongodb, node
Published: 2024-06-25 08:57:49

## Opening:

Building a web application from scratch can be a daunting task, especially for beginners. However, with the MERN stack, the process becomes more manageable and even enjoyable. In this blog post, I will walk you through the process of creating a full-stack web application using MongoDB, Express.js, React, and Node.js. By the end of this guide, you'll have a functioning web app and a solid understanding of how these technologies work together.

## Table of Contents
1. [Opening](#opening)
2. [Introduction](#introduction)
3. [Setting Up Your Development Environment](#1-setting-up-your-development-environment)
4. [Initialize Your Project](#2-initialize-your-project)
5. [Set Up the Backend with Express.js and MongoDB](#3-set-up-the-backend-with-expressjs-and-mongodb)
6. [Create MongoDB Data Models](#4-create-mongodb-data-models)
7. [Create Routes for CRUD Operations](#5-create-routes-for-crud-operations)
8. [Connect Routes to the Server](#6-connect-routes-to-the-server)
9. [Set Up the Frontend with React](#7-set-up-the-frontend-with-react)
10. [Connecting Frontend to Backend](#8-connecting-frontend-to-backend)
11. [Summary](#9-summary)
12. [Conclusion](#10-conclusion)

## Introduction

The MERN stack comprises four key technologies that work together to create a seamless full-stack web development experience:

- **MongoDB**: A NoSQL database that stores data in flexible, JSON-like documents.
- **Express.js**: A web application framework for Node.js, used to build backend services.
- **React**: A JavaScript library for building user interfaces, particularly single-page applications.
- **Node.js**: A JavaScript runtime built on Chrome's V8 engine, used for server-side development.

## 1. Setting Up Your Development Environment

Before we dive into the code, ensure you have the following software installed on your computer:

- **Node.js** and npm: Download and install from [nodejs.org](https://nodejs.org/).
- **MongoDB**: Install MongoDB Community Server from [mongodb.com](https://www.mongodb.com/try/download/community).
- **Code Editor**: Use a code editor like Visual Studio Code, which you can download from code.[visualstudio.com](https://code.visualstudio.com/).

## 2. Initialize Your Project

Create a new directory for your project and navigate into it. Then, initialize a new `Node.js` project:

```bash
mkdir mern-app
cd mern-app
npm init -y
```


## 3. Set Up the Backend with Express.js and MongoDB

Install Express.js, Mongoose (an ODM for MongoDB), and some other essential packages:

```bash
npm install express mongoose body-parser cors dotenv
```

Create a file named `server.js` and set up your Express server:

```js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(bodyParser.json());

// MongoDB connection
mongoose.connect(process.env.DB_CONNECTION)
  .then(() => console.log('Connected to database'))
  .catch((error) => console.log(error));

app.get('/', (req, res) => {
  res.send('Hello, MERN!');
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
```

## 4. Create MongoDB Data Models

Create a folder named `models` and add a file named `Post.js`:

```js
const mongoose = require('mongoose');

const PostSchema = mongoose.Schema({
  title: {
    type: String,
    required: true
  },
  content: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = mongoose.model('Posts', PostSchema);
```

## 5. Create Routes for CRUD Operations

Create a folder named `routes` and add a file named `posts.js`:

```js
const express = require('express');
const router = express.Router();
const Post = require('../models/Post');

// Get all posts
router.get('/', async (req, res) => {
  try {
    const posts = await Post.find();
    res.json(posts);
  } catch (err) {
    res.json({ message: err });
  }
});

// Create a new post
router.post('/', async (req, res) => {
  const post = new Post({
    title: req.body.title,
    content: req.body.content
  });

  try {
    const savedPost = await post.save();
    res.json(savedPost);
  } catch (err) {
    res.json({ message: err });
  }
});

module.exports = router;
```

## 6. Connect Routes to the Server

In `server.js`, import and use the routes:

```js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const postsRoute = require('./routes/posts'); // Import the routes
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(bodyParser.json());
app.use('/posts', postsRoute); // Use the imported routes

// MongoDB connection
mongoose.connect(process.env.DB_CONNECTION, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to database'))
  .catch((error) => console.log(error));

app.get('/', (req, res) => {
  res.send('Hello, MERN!');
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
```

## 7. Set Up the Frontend with React

Create a new React application in the `client` directory:

```sh
npm create vite@latest -- --template react client
cd client
npm run dev
```

The command `npm create vite@latest -- --template react client` is used to set up a new project using `Vite`, specifying the use of the `React template`. Here's a breakdown of the command:

- *npm create*: This is a command utilized to scaffold a new project using a package that provides a create script.
- *vite@latest*: This refers to the Vite package at its latest version. Vite is a modern frontend build tool that significantly improves the development experience.
- *-- --template react*: Here, `--` signals the end of command options for `npm create`, and the subsequent `--template react` tells Vite to use a template preset for a React application.
- *client*: This is likely the name of the directory where your new project will be created.

## 8. Connecting Frontend to Backend

In your React application, install `Axios` to handle HTTP requests:

```sh
npm install axios
```

Create a new component to display posts from your backend:
// App.jsx
```jsx
import React, { useEffect, useState } from 'react';
import axios from 'axios';

function Posts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:5000/posts')
      .then(response => {
        setPosts(response.data);
      })
      .catch(error => {
        console.error('There was an error fetching the posts!', error);
      });
  }, []);

  return (
    <div>
      <h1>Posts</h1>
      {posts.map(post => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
}

export default Posts;
```

## 9. Summary
Congratulations! You've just built a full-stack web application using the MERN stack. You've learned how to set up a server with Express.js, create data models with Mongoose, and build a responsive frontend with React. As you continue your journey in software development, the skills you’ve acquired here will serve as a strong foundation for building more complex web applications.

## Conclusion
Building a web application using the MERN stack is an excellent way to develop your skills in both front-end and back-end technologies. The process may seem challenging at first, but with practice and dedication, you'll find it increasingly rewarding. Keep experimenting, keep learning, and soon you'll be creating advanced applications with ease. Happy coding!

> Follow me for more useful contents:
[Dev](https://dev.to/princenzmw)
[LinkedIn](https://www.linkedin.com/in/princenzmw/)
[GitHub](https://www.github.com/princenzmw)