Open In App

How To Use MERN Stack: A Complete Guide

Last Updated : 01 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The MERN stack, comprising MongoDB, ExpressJS, ReactJS, and NodeJS, is a powerful framework for building modern web applications. MongoDB offers a scalable NoSQL database, ExpressJS simplifies server-side development, ReactJS creates dynamic user interfaces, and NodeJS enables server-side JavaScript execution. In this article, we will see how To Use MERN Stack: A Complete Guide.

What is MERN Stack?

MERN is for MongoDB, ExpressJS, ReactJS, & NodeJS. It is an integrated technology for modern web applications.

  • MongoDB: A NoSQL database that stores data in JSON-like documents. It’s flexible and scalable, perfect for handling more amounts of data.
  • ExpressJS: A web application framework for Node.Js. It simplifies the process of constructing internet programs and APIs with the aid of providing a strong set of functions.
  • ReactJS: A JavaScript library for constructing consumer interfaces. It permits builders to create reusable UI additives and build interactive web programs correctly.
  • NodeJS: A JavaScript runtime surroundings that authorises you to run JavaScript code out of the doors of an internet browser.

Installing the MERN Stack

  1. NodeJS installation: Click to the Node.js website and download the installer for your own operating system. Follow the installation instructions to install in your device.
  2. Installing MongoDB: MongoDB provides installation for various operating systems on its network. Download and install MongoDB Community Edition.
  3. Create a New Project Directory: Open your terminal or command prompt or create a new directory on your MERN stack project.
  4. Initialize Your Project: Inside your project directory, initialize a new Node.js project by working npm init -y. This will create a package.json file.
  5. Install Dependencies: Install the necessary dependencies for your project:
npm install express mongoose

Building backend (Node.js + Express.js + MongoDB)

1. Initialize the node application

npm init -y

2. Configure Your Server: Create a new file called server.js, and import Express.js.

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

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

3. Connect to MongoDB: Install the mongoose package and connect your Express.js application to MongoDB.

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database',
{ useNewUrlParser: true, useUnifiedTopology: true });

3. Create API Endpoints: Define routes to handle HTTP requests. To create a simple API endpoint for fetch data.

app.get('/api/data', (req, res) => {
// Fetch data from MongoDB
res.json({ message: 'Data fetched successfully' });
});

Building the Frontend (React.js)

1. Create React App: Run the following command in your terminal to create a new React.js app inside your project directory:

npx create-react-app client

2. Proxy setting: Open the package.json file inside, the client directory and add a proxy to forward API requests to Express.js server.

"proxy": "http://localhost:5000"

3. Fetch Data from Backend: Inside your React components, use the fetch API or libraries like axios to fetch data from your Express.js backend.

fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));

Putting It All Together

  1. Deploy your application: Start your Express.js server by running node server.js in a terminal window. Now, go to the client directory and run "npm start" to start the React development server.
  2. Build your application: Once you are ready to deploy your application, run "npm run build" from the client directory and create the React app. This will have your React app ready to be built in the build folder.
  3. Deploy your application: You can deploy your MERN stack application to platforms such as Heroku, AWS, or DigitalOcean. Be sure to configure your deployment environment correctly, including setting environment variables for important information.

You have now developed a full stack web application using the MERN stack. Keep exploring and experimenting to create even more powerful and robust applications.

Step 1: Setup and Installation

1. Install Node.js and MongoDB

Ensure you have Node.js and MongoDB installed on your machine. You can download them from their official websites.

2. Create Project Directory

mkdir mern-todo-app
cd mern-todo-app

Step 2: Initialize the Backend (Express & MongoDB)

1. Initialize a Node.js Project

npm init -y

2. Install Dependencies

 npm install express mongoose cors body-parser

3. Create Folder Structure

mkdir backend
cd backend
mkdir models routes
touch server.js

4. Create server.js

JavaScript
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

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

// Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// MongoDB connection URI
const uri = 'add_your_mongoDB-URI';

// Connect to MongoDB
mongoose.connect(uri, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    serverSelectionTimeoutMS: 5000,
}).catch(err => console.error(err));

// Check connection
const connection = mongoose.connection;
connection.once('open', () => {
    console.log('MongoDB database connection established successfully');
}).on('error', (error) => {
    console.error('MongoDB connection error:', error);
});

// Mongoose Todo model
const todoSchema = new mongoose.Schema({
    title: { type: String, required: true },
    completed: { type: Boolean, default: false },
}, { timestamps: true });

const Todo = mongoose.model('Todo', todoSchema);

// Routes
app.get('/todos', (req, res) => {
    Todo.find()
        .then(todos => res.json(todos))
        .catch(err => res.status(400).json('Error: ' + err));
});

app.post('/todos/add', (req, res) => {
    const newTodo = new Todo({
        title: req.body.title,
    });

    newTodo.save()
        .then(() => res.json('Todo added!'))
        .catch(err => res.status(400).json('Error: ' + err));
});

// Start server
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

Note: Make sure that it has your mongodb credentials like urls and password, So that it will connect to the mongodb. Also include your IP address in your mongodb collection, otherwise it won't access your data.

5. Create a Mongoose Model (models/Todo.js)

JavaScript
const mongoose = require('mongoose');

const TodoSchema = new mongoose.Schema({
    task: String,
    completed: {
        type: Boolean,
        default: false
    }
});

module.exports = mongoose.model('Todo', TodoSchema);

6. Create Routes (routes/todoRoutes.js)

JavaScript
const express = require('express');
const router = express.Router();
const Todo = require('../models/Todo');

// Get all todos
router.get('/', async (req, res) => {
    const todos = await Todo.find();
    res.json(todos);
});

// Create a new todo
router.post('/', async (req, res) => {
    const newTodo = new Todo({
        task: req.body.task
    });
    await newTodo.save();
    res.json(newTodo);
});

// Update a todo
router.put('/:id', async (req, res) => {
    const updatedTodo = await Todo.findByIdAndUpdate
        (req.params.id, req.body, { new: true });
    res.json(updatedTodo);
});

// Delete a todo
router.delete('/:id', async (req, res) => {
    await Todo.findByIdAndDelete(req.params.id);
    res.json({ message: 'Todo deleted' });
});

module.exports = router;

Step 3: Initialize the Frontend (React)

1. Create React App

npx create-react-app frontend
cd frontend

2. Install Dependencies

npm install axios

3. Folder Structure

Create the following folders and files in src:

cd src
mkdir components
touch components/Todo.js
touch components/TodoList.js
touch components/AddTodo.js
touch App.css

4. Create Components

JavaScript
//AddTodo.js

import React, { useState } from 'react';
import axios from 'axios';

const AddTodo = ({ addTodo }) => {
    const [title, setTask] = useState('');

    const handleSubmit = async (e) => {
        e.preventDefault();
        if (title) {
            const response = await axios.post('http://localhost:5000/todos/add', { title });
            addTodo(response.data);
            setTask('');
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                value={title}
                onChange={(e) => setTask(e.target.value)}
                placeholder="Add new task"
            />
            <button type="submit">Add</button>
        </form>
    );
};

export default AddTodo;
JavaScript
//Todo.js

import React from 'react';
import './Todo.css';

function Todo({ todo, removeTodo, updateTodo }) {
    const handleRemove = () => {
        removeTodo(todo._id);
    };

    const toggleCompleted = () => {
        updateTodo({ ...todo, completed: !todo.completed });
    };

    return (
        <div className={`todo-item ${todo.completed ? 'completed' : ''}`}>
            <span onClick={toggleCompleted} className="todo-text">
                {todo.title}
            </span>
            <button onClick={handleRemove} className="todo-remove-button">
                Remove
            </button>
        </div>
    );
}

export default Todo;
JavaScript
//TodoList.js

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import Todo from './Todo';
import AddTodo from './AddTodo';
import './TodoList.css';

const TodoList = () => {
    const [todos, setTodos] = useState([]);

    useEffect(() => {
        const fetchTodos = async () => {
            const response = await axios.get('http://localhost:5000/todos');
            setTodos(response.data);
        };
        fetchTodos();
    }, []);

    const addTodo = (todo) => {
        setTodos([...todos, todo]);
    };

    const removeTodo = (id) => {
        setTodos(todos.filter(todo => todo._id !== id));
    };

    const updateTodo = (updatedTodo) => {
        setTodos(todos.map(todo => (todo._id === updatedTodo._id ? updatedTodo : todo)));
    };

    return (
        <div className="todo-list-container">
            <h1 className="todo-list-title">To-Do List</h1>
            <AddTodo addTodo={addTodo} />
            <div className="todos">
                {todos.map(todo => (
                    <Todo key={todo._id} todo={todo} 
                    removeTodo={removeTodo} updateTodo={updateTodo} />
                ))}
            </div>
        </div>
    );
};

export default TodoList;
JavaScript
//App.js

import React from 'react';
import './App.css';
import TodoList from './components/TodoList';

function App() {
    return (
        <div className="App">
            <TodoList />
        </div>
    );
}

export default App;

Step 4: Add Some CSS to give good look.

CSS
/* Todo.css */

.todo-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px;
    margin-bottom: 10px;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    transition: background-color 0.3s;
}

.todo-item.completed {
    background-color: #e0ffe0;
    text-decoration: line-through;
}

.todo-text {
    flex-grow: 1;
    cursor: pointer;
}

.todo-remove-button {
    background-color: #ff4d4d;
    color: white;
    border: none;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.todo-remove-button:hover {
    background-color: #cc0000;
}
CSS
/* App.css */

.App {
    text-align: center;
}

.App-logo {
    height: 40vmin;
    pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
    .App-logo {
        animation: App-logo-spin infinite 20s linear;
    }
}

.App-header {
    background-color: #282c34;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: calc(10px + 2vmin);
    color: white;
}

.App-link {
    color: #61dafb;
}

@keyframes App-logo-spin {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}
CSS
/* TodoList.css */

.todo-list-container {
    max-width: 600px;
    margin: 50px auto;
    padding: 20px;
    background-color: #f1f1f1;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.todo-list-title {
    text-align: center;
    color: #333;
    margin-bottom: 20px;
    font-size: 2em;
}

.todos {
    margin-top: 20px;
}

Step 5: Run the Application

1. Start MongoDB

Ensure your MongoDB server is running:

mongod

2. Start Backend Server

In the backend directory:

node server.js

3. Start React Frontend

In the frontend directory:

npm start

Folder Structure Overview

For Front End :-

structure
Front End Structure

For Back End :-

structureBackend
Backend Structure

Dependencies

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},

Output

ReactApp-GoogleChrome2024-06-2918-51-21-ezgifcom-video-to-gif-converter
How To Use MERN Stack: A Complete Guide

Conclusion

By following this guide, you have built a full-stack web application using the MERN stack. You've learned to install Node.js and MongoDB, set up the backend with Express.js, connect to MongoDB using Mongoose, and create a dynamic frontend with React.js. With your application now deployed, you have a robust foundation for further development and optimization. The MERN stack offers a streamlined, efficient approach to building powerful web applications. Continue exploring and enhancing your skills to make the most of this versatile technology stack.


Next Article
Article Tags :

Similar Reads