MERN Stack Tutorial: Creating a Real-Time Chat Application from Scratch
In this tutorial, we will learn how to build a real-time chat application using the MERN (MongoDB, Express, React, and Node.js) stack. The MERN stack is a popular choice for building modern web applications, and it’s ideal for creating real-time applications like chat apps. By the end of this tutorial, you’ll have a fully functional chat application that allows users to send and receive messages in real-time.
Prerequisites
Before we begin, make sure you have the following installed on your machine:
- Node.js (version 14 or higher)
- MongoDB (version 4 or higher)
- A code editor or IDE of your choice
- Basic knowledge of JavaScript, HTML, and CSS
Step 1: Setting up the Project Structure
Create a new project folder and navigate to it in your terminal or command prompt. Run the following command to initialize a new Node.js project:
bash
npm init
Fill in the required information, and then install the following dependencies:
bash
npm install express mongoose socket.io react react-dom
Create the following folders and files:
server: This folder will contain our server-side code.client: This folder will contain our client-side code.models: This folder will contain our database models.index.js: This file will be the entry point of our server.package.json: This file contains metadata for our project.
Step 2: Setting up the Server
In the server folder, create a new file called index.js. This file will contain our server-side code. Add the following code to get started:
javascript
const express = require(‘express’);
const app = express();
const http = require(‘http’).createServer(app);
const io = require(‘socket.io’)(http);
const mongoose = require(‘mongoose’);
mongoose.connect(‘mongodb://localhost:27017/chat-app’, { useNewUrlParser: true, useUnifiedTopology: true });
app.use(express.static(‘client’));
http.listen(3000, () => {
console.log(‘Server listening on port 3000’);
});
This code sets up an Express server, creates a new HTTP server, and sets up Socket.IO for real-time communication. It also connects to our MongoDB database.
Step 3: Creating the Database Model
In the models folder, create a new file called message.js. This file will contain our database model for messages. Add the following code:
javascript
const mongoose = require(‘mongoose’);
const messageSchema = new mongoose.Schema({
text: String,
sender: String,
receiver: String,
timestamp: Date
});
const Message = mongoose.model(‘Message’, messageSchema);
module.exports = Message;
This code defines a new Mongoose model for messages, which will be used to store and retrieve messages from our database.
Step 4: Creating the Client-Side Code
In the client folder, create a new file called index.js. This file will contain our client-side code. Add the following code:
javascript
import React, { useState, useEffect } from ‘react’;
import ReactDOM from ‘react-dom’;
import io from ‘socket.io-client’;
const socket = io(‘http://localhost:3000‘);
function App() {
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState(”);
const [username, setUsername] = useState(”);
useEffect(() => {
socket.on(‘connect’, () => {
console.log(‘Connected to server’);
});
socket.on('message', (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});
}, []);
const handleSendMessage = () => {
socket.emit(‘message’, { text: newMessage, sender: username });
setNewMessage(”);
};
return (
-
{messages.map((message, index) => (
- {message.text}
))}
);
}
ReactDOM.render(
This code sets up a basic React app that connects to our server using Socket.IO. It also defines a few state variables to store the messages, new message, and username.
Step 5: Handling Socket Events
In the server folder, add the following code to index.js to handle socket events:
javascript
io.on(‘connection’, (socket) => {
console.log(‘Client connected’);
socket.on(‘message’, (message) => {
const newMessage = new Message(message);
newMessage.save((err) => {
if (err) {
console.error(err);
} else {
io.emit(‘message’, message);
}
});
});
socket.on(‘disconnect’, () => {
console.log(‘Client disconnected’);
});
});
This code handles the connection event, which is emitted when a client connects to the server. It also handles the message event, which is emitted when a client sends a message. When a message is received, it creates a new message document in the database and emits the message event to all connected clients.
Step 6: Running the Application
Start the server by running the following command:
node server/index.js
Open two or more browser windows and navigate to http://localhost:3000. You should see a basic chat interface where you can send and receive messages in real-time.
Conclusion
In this tutorial, we built a real-time chat application using the MERN stack. We set up a server using Express and Socket.IO, created a database model using Mongoose, and built a client-side interface using React. We also handled socket events to enable real-time communication between clients. This is just a basic example, and you can improve it by adding features like user authentication, message editing, and deletion.