Welcome to Retro_Chat, a modern and super smooth real-time chat application designed to bring your conversations to life! Built with the robust MERN stack (MongoDB, Express.js, React, Node.js) and powered by the lightning-fast Socket.IO, this application ensures instant live messaging, creating a seamless and engaging user experience.
Retro_Chat allows you to connect and chat 1-to-1 with your friends, providing real-time updates on their online/offline status. The user interface is crafted with a fully responsive design using TailwindCSS, ensuring a beautiful and functional experience across all devices. Dive in now and experience the magic of instant communication with a touch of retro charm!
- Real-time 1-to-1 Chat: Engage in instant, live conversations with your friends.
- Online/Offline Status: See who's currently available with clear status indicators.
- MERN Stack Powered: A robust and scalable foundation using MongoDB, Express.js, React, and Node.js.
- Socket.IO Integration: Ensures lightning-fast message delivery and real-time updates.
- Responsive Design: Enjoy a consistent and beautiful experience on any device, thanks to TailwindCSS.
- User Authentication: Secure signup and login functionality.
| Category | Technology | Description |
|---|---|---|
| Frontend | React | UI Library |
| Vite | Fast Frontend Tooling | |
| TailwindCSS | Utility-first CSS framework | |
| Zustand | State Management | |
| Backend | Node.js | JavaScript Runtime |
| Express.js | Web Framework | |
| Socket.IO | Real-time bidirectional event-based communication | |
| Database | MongoDB | NoSQL Database |
| Authentication | JWT | JSON Web Tokens for secure authentication |
Follow these instructions to get a copy of the project up and running on your local machine for development and testing purposes.
Before you begin, ensure you have the following installed:
- Node.js (LTS version recommended)
- npm (comes with Node.js)
- MongoDB (local or cloud-based service like MongoDB Atlas)
- Git
-
Clone the repository:
git clone https://github.com/himanshuvkm/Retro_Chat.git cd Retro_Chat -
Install client dependencies:
cd Client npm install -
Install server dependencies:
cd ../Server npm install
-
Create a
.envfile in theServerdirectory:touch .env
-
Add the following environment variables to
Server/.env:PORT=5000 MONGO_DB_URI="YOUR_MONGODB_CONNECTION_STRING" JWT_SECRET="YOUR_JWT_SECRET_KEY" NODE_ENV=development # or production
- Replace
"YOUR_MONGODB_CONNECTION_STRING"with your MongoDB connection string (e.g., from MongoDB Atlas or a local instance). - Replace
"YOUR_JWT_SECRET_KEY"with a strong, random string for JWT token signing.
- Replace
-
Start the client development server:
cd Client npm run devThe client application will typically run on
http://localhost:5173. -
Start the server:
cd ../Server npm run devThe server will typically run on
http://localhost:5000.
Now, open your browser and navigate to http://localhost:5173 to access the Retro_Chat application.
Once the application is running, you can:
- Sign Up: Create a new account with a username, password, and gender.
- Log In: Access your account using your credentials.
- Find Friends: The sidebar will display available users.
- Start a Chat: Click on a user's name in the sidebar to open a conversation.
- Send Messages: Type your message in the input field and press Enter or click the send button.
- Real-time Updates: See messages appear instantly and monitor online/offline statuses.
Example of sending a message (frontend logic):
// Client/src/Hooks/useSendMessage.js
import { useState } from "react";
import useConversation from "../zustand/useconversation";
import toast from "react-hot-toast";
const useSendMessage = () => {
const [loading, setLoading] = useState(false);
const { messages, setMessages, selectedConversation } = useConversation();
const sendMessage = async (message) => {
setLoading(true);
try {
const res = await fetch(`/api/messages/send/${selectedConversation._id}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ message }),
});
const data = await res.json();
if (data.error) {
throw new Error(data.error);
}
setMessages([...messages, data]);
} catch (error) {
toast.error(error.message);
} finally {
setLoading(false);
}
};
return { sendMessage, loading };
};
export default useSendMessage;Example of a server-side message route:
// Server/routes/message.routes.js (conceptual)
router.post("/send/:id", protectRoute, sendMessage);// Server/controllers/message.controller.js (conceptual)
import Conversation from "../models/conversation.model.js";
import Message from "../models/message.model.js";
import { getReceiverSocketId, io } from "../socket/socket.js";
export const sendMessage = async (req, res) => {
try {
const { message } = req.body;
const { id: receiverId } = req.params;
const senderId = req.user._id;
let conversation = await Conversation.findOne({
participants: { $all: [senderId, receiverId] },
});
if (!conversation) {
conversation = await Conversation.create({
participants: [senderId, receiverId],
});
}
const newMessage = new Message({
senderId,
receiverId,
message,
});
if (newMessage) {
conversation.messages.push(newMessage._id);
}
// await conversation.save();
// await newMessage.save();
// This will run in parallel
await Promise.all([conversation.save(), newMessage.save()]);
// SOCKET IO FUNCTIONALITY WILL GO HERE
const receiverSocketId = getReceiverSocketId(receiverId);
if (receiverSocketId) {
// io.to(<socket_id>).emit() used to send events to specific client
io.to(receiverSocketId).emit("newMessage", newMessage);
}
res.status(201).json(newMessage);
} catch (error) {
console.log("Error in sendMessage controller