Socket.io Chat App with Vite+React

Sai Chinmay Tripurari
3 min readSep 26, 2024

--

Getting Started with Chat Application

First lets create the Folder Structure for our Application

mkdir chat-app
cd chat-app

Now Create the Backend Folder Structure

mkdir chat-backend
cd chat-backend
npm init -y

Now install all the below required dependencies for our application.

npm install express socket.io

Create index.js in the root of the chat-backend project folder.

index.js

In Package.json file add a start script.

"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
}

Now we will get started with the Express and Socket.io

Firstly we will import the required modules for our backend application.

const express = require('express')
const http = require('http')
const {Server} = require('socket.io')

Now lets create server with express and socket

This code sets up Socket.io to handle real-time communication and installs an Express server that listens on port 4000. A message (sendMessage event) sent by a user is broadcast to all clients that are connected.

const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors:{
origin: "http://localhost:5173",
methods: ['GET','POST']
}
})

io.on('connection', (socket) => {
console.log("A user connected: ", socket.id);
socket.on('sendMessage', (message) => {
io.emit('receiveMessage', message)
})
socket.on('disconnect', () => {
console.log("A user disconnected");
})
})

server.listen(4000, () => {
console.log("Server Listening on port 4000");
})

Now lets get started with our Frontend part using Vite. (Create a Vite Project in the root folder of Chat App).

npm create vite@latest
Select React Framework
Select Javascript variant

Next, we need to install a few dependencies. Navigate to the frontend app folder.

cd chat-frontent
npm install socket.io-client @chakra-ui/react @emotion/react @emotion/styled framer-motion

The following represents the structure of the frontend application:

chat-frontend/

├── src/
│ ├── components/
│ │ └── ChatBox.jsx
│ ├── App.jsx
│ └── main.jsx
├── index.html
└── package.json

Now let’s code the App.jsx file

import { ChakraProvider, Box, Heading } from "@chakra-ui/react";
import ChatBox from "./components/ChatBox";

function App() {
return (
<ChakraProvider>
<Box p={5}>
<Heading as="h1" mb={6}>
Socket Chat
</Heading>
<ChatBox />
</Box>
</ChakraProvider>
);
}

export default App;

ChatBox.jsx

import React, { useState, useEffect } from "react";
import { Box, Input, Button, HStack, VStack, Text, Avatar } from "@chakra-ui/react";
import { io } from "socket.io-client";

const socket = io("http://localhost:4000");

const ChatBox = () => {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
const [userId, setUserId] = useState(null);

useEffect(() => {
// Generate or get userId from session storage
let storedUserId = sessionStorage.getItem("userId");
if (!storedUserId) {
storedUserId = Math.random().toString(36).substring(7);
sessionStorage.setItem("userId", storedUserId);
}
setUserId(storedUserId);

// Listen for messages
socket.on("receiveMessage", (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});

return () => {
socket.off("receiveMessage");
};
}, []);

const sendMessage = () => {
if (input.trim()) {
const message = {
userId,
text: input,
};
socket.emit("sendMessage", message);
setInput("");
}
};

console.log(messages,"MESSAGES");

return (
<VStack spacing={4} align="stretch">
<Box h="400px" p={4} borderWidth={1} borderRadius="lg" overflowY="auto">
{messages.map((msg, index) => (
<HStack key={index} justify={msg.userId === userId ? "flex-start" : "flex-end"}>
{msg.userId === userId && <Avatar name="Me" />}
<Box
bg={msg.userId === userId ? "blue.100" : "green.100"}
p={3}
borderRadius="lg"
maxW="70%"
>
<Text>{msg.text}</Text>
</Box>
{msg.userId !== userId && <Avatar name="Other" />}
</HStack>
))}
</Box>

<HStack>
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message"
/>
<Button onClick={sendMessage} colorScheme="teal">
Send
</Button>
</HStack>
</VStack>
);
};

export default ChatBox;

The Final Result

--

--

Sai Chinmay Tripurari
Sai Chinmay Tripurari

Written by Sai Chinmay Tripurari

Software Developer | ReactJS & React Native Expert | AI & Cloud Enthusiast | Building intuitive apps, scalable APIs, and exploring AI-driven solutions.

No responses yet