<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Minhaj Tapader </title>
    <description>The latest articles on DEV Community by Minhaj Tapader  (@tapader13).</description>
    <link>https://dev.to/tapader13</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1467989%2Fa396ff7d-2853-4925-be68-7bb8c0928221.jpg</url>
      <title>DEV Community: Minhaj Tapader </title>
      <link>https://dev.to/tapader13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tapader13"/>
    <language>en</language>
    <item>
      <title>Database Normalization: A Complete Guide to 1NF, 2NF, 3NF, and BCNF</title>
      <dc:creator>Minhaj Tapader </dc:creator>
      <pubDate>Fri, 27 Jun 2025 10:19:22 +0000</pubDate>
      <link>https://dev.to/tapader13/database-normalization-a-complete-guide-to-1nf-2nf-3nf-and-bcnf-1j1a</link>
      <guid>https://dev.to/tapader13/database-normalization-a-complete-guide-to-1nf-2nf-3nf-and-bcnf-1j1a</guid>
      <description>&lt;h2&gt;
  
  
  What is normalization in DBMS?
&lt;/h2&gt;

&lt;p&gt;Database normalization is a process by which the database structure can be designed in a very effective way. Normalization in DBMS reduces the repetition of data and increases the integrity of data. In this process, various relational tables are created and duplicate data is removed from them. As a result, data repetition is reduced and data is not lost when inserting, deleting, updating.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is normalization needed?
&lt;/h2&gt;

&lt;p&gt;Suppose you are creating a student information system. There is only one table in which all the information of the student (name, course, teacher) is stored. Now if you want to delete the information of a teacher, then the student's info along with the teacher and the course info will also be deleted. We will normalize so that the data is not lost during the CRUD operation. Here you have to create a separate table for students, courses, teachers through normalization so that data integrity is maintained while doing CRUD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalization steps:
&lt;/h2&gt;

&lt;p&gt;Normalization is usually carried out in several steps. Each step is called a normalization form (NF). Such as 1NF, 2NF, 3NF, BCNF etc. Below are some of the key steps: &lt;/p&gt;

&lt;h2&gt;
  
  
  First Normal Form (1NF)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Condition:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The table must not contain any repeating groups.&lt;/li&gt;
&lt;li&gt;All column values ​​must be atomic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;

&lt;p&gt;Before normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxipzcednlft597r9awc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxipzcednlft597r9awc.png" alt="Before normalization" width="580" height="173"&gt;&lt;/a&gt;&lt;br&gt;
After normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaopl8xqubxa894gb6vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaopl8xqubxa894gb6vg.png" alt="After normalization" width="570" height="284"&gt;&lt;/a&gt;&lt;br&gt;
The values of the subjects column in the table above are not atomic. Because in this column, different values are placed inside a column with a comma. So the 1NF values are placed in different rows. Now each column has an atomic value that satisfies the condition of 1NF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Normal Form (2NF)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Condition:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The table must be in 1NF. &lt;/li&gt;
&lt;li&gt;There must be no partial dependency (non-key columns must depend on the entire primary key).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;

&lt;p&gt;Before normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k015wmyx0ogszqjhve4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k015wmyx0ogszqjhve4.png" alt="Before normalization" width="800" height="294"&gt;&lt;/a&gt;&lt;br&gt;
After normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2arufla4u7vt6x78lcpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2arufla4u7vt6x78lcpz.png" alt="After normalization" width="428" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjsifq7jdvn0019p4y9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjsifq7jdvn0019p4y9z.png" alt="After normalization" width="417" height="339"&gt;&lt;/a&gt;&lt;br&gt;
In the table above, StudentID + CourseID is the composite key. But CourseName does not depend on the entire composite key. It depends only on the CourseID so this is a partial dependency. Similarly, in the case of StudentName, it does not depend on the entire composite key. It depends only on the StudentID so this is also a partial dependency. Now after normalizing this is divided into two tables. The non-key columns in each table are now dependent on the entire primary key, which means there is no longer any partial dependency that meets the 2NF condition. &lt;/p&gt;

&lt;h2&gt;
  
  
  Third Normal Form (3NF)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Condition:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The table must be in 2NF.&lt;/li&gt;
&lt;li&gt;There must be no transitive dependencies (non-key columns cannot be dependent on any other non-key column).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;

&lt;p&gt;Before normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pve1hxest0vzg36szbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pve1hxest0vzg36szbr.png" alt="Before normalization" width="800" height="225"&gt;&lt;/a&gt;&lt;br&gt;
After normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87qsg2m9th10vngxsiaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87qsg2m9th10vngxsiaw.png" alt="After normalization" width="726" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24n859xj1sro4nnkyxcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24n859xj1sro4nnkyxcx.png" alt="After normalization" width="493" height="282"&gt;&lt;/a&gt;&lt;br&gt;
In the table above, StudentID is the primary key that uniquely identifies each row. Here the DepartmentName depends on the DepartmentID and the DepartmentID depends on the StudentID which basically creates a transitive dependency. Because when a non-key column (DepartmentName) depends on another non-key column (DepartmentID), it is called a transitive dependency. Since there is a transitive dependency, two tables have been created by normalizing this table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boyce-Codd Normal Form (3.5NF)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Condition:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The table must be in 3NF.&lt;/li&gt;
&lt;li&gt;Each determinant must be a candidate key. A determinant is a column or set of columns that determines another column.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;

&lt;p&gt;Before normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tin603lcapd4giyi75x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tin603lcapd4giyi75x.png" alt="Before normalization" width="615" height="283"&gt;&lt;/a&gt;&lt;br&gt;
After normalization&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fb6dxp802iw731xtz3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fb6dxp802iw731xtz3t.png" alt="After normalization" width="428" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1vb9p5feod0e0vc01m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1vb9p5feod0e0vc01m.png" alt="After normalization" width="431" height="170"&gt;&lt;/a&gt;&lt;br&gt;
In the table above, StudentID + CourseID is the candidate key. Functional dependency is CourseID- &amp;gt; Instructor but here CourseID is not a candidate key but it is part of the candidate key so it violates the condition of BCNF. So now two new tables have been created through normalization so that the Determinant is always the candidate key. Actually, BCNF is an updated version of 3NF. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of normalization:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reduces data redundancy.&lt;/li&gt;
&lt;li&gt;Maintains data consistency.&lt;/li&gt;
&lt;li&gt;It is easy to update the data.&lt;/li&gt;
&lt;li&gt;Storage can be saved. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>developer</category>
      <category>learning</category>
    </item>
    <item>
      <title>Socket.IO for Beginners: Build a Live Online Users Tracker with MERN</title>
      <dc:creator>Minhaj Tapader </dc:creator>
      <pubDate>Thu, 19 Jun 2025 22:24:02 +0000</pubDate>
      <link>https://dev.to/tapader13/socketio-for-beginners-build-a-live-online-users-tracker-with-mern-1ibj</link>
      <guid>https://dev.to/tapader13/socketio-for-beginners-build-a-live-online-users-tracker-with-mern-1ibj</guid>
      <description>&lt;h3&gt;
  
  
  What is Socket.IO?
&lt;/h3&gt;

&lt;p&gt;Socket.IO is a JavaScript library used for real-time data exchange between client and server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why should you use Socket.IO?
&lt;/h3&gt;

&lt;p&gt;You can use Socket.IO when you need to implement real-time features in your project. With this, you can update the data in real time. Once connected, both the client and the server can exchange data in real time. Socket.IO uses Event based communication. For example, you can create an event and then send and receive it to both the client and the server. With the help of Socket.IO you can handle hundreds of connections if you want. Socket.IO can be used in various places such as: chat applications, online games, real-time notifications, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required Setup:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You need to have a basic understanding of JavaScript, React.js, Node.js, Mongoose, and npm.
&lt;/li&gt;
&lt;li&gt;VS Code and Node.js must be installed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Project Setup:
&lt;/h3&gt;

&lt;p&gt;Now I will create a folder named project. This will be the main project folder. Inside it, I will create two more folders named client and server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a project directory:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir project
cd project
mkdir server
mkdir client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Backend:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd server
npm init -y
npm i mongoose express cors dotenv nodemon validator
npm i socket.io (This package is used to implement socket.IO)
code .

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Express server:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inside server/index.js, write the server code to initialize the server.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import dotenv from 'dotenv';
import { app, server } from './socket/socket.js';
import cors from 'cors';

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
import connectDB from './config/db.js';
import userRoutes from './route/userRoute.js';

dotenv.config();
connectDB();
const PORT = process.env.PORT || 3000;

app.use('/api/users', userRoutes);
server.listen(PORT, () =&amp;gt; {
  console.log(`Server running on port ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside socket / socket.js Here you need to write the code to initialize the socket and then connect to the server. You can create any real time event within the connection. Here I am just creating an event to see how many people are online after creating the user and sending it to the UI. The getOnlineUsers event will return an array that contains the IDs of the online users.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import http from 'http';
import { Server } from 'socket.io';

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: process.env.CLIENT_URL,
    methods: ['GET', 'POST'],
  },
});
let userConnections = {};
export const getReciverSocketId = (reciverId) =&amp;gt; userConnections[reciverId];

io.on('connection', (socket) =&amp;gt; {
  console.log('socket', socket.handshake.query);
  const { userId } = socket.handshake.query;
  if (userId) {
    userConnections[userId] = socket.id;
    console.log(`User ${userId} connected and socket id is ${socket.id}`);
  }
  io.emit('getOnlineUsers', Object.keys(userConnections));
  console.log('userConnections', userConnections);
  socket.on('disconnect', () =&amp;gt; {
    if (userId) {
      delete userConnections[userId];
      console.log(`User ${userId} disconnected and socket id is ${socket.id}`);
    }
    io.emit('getOnlineUsers', Object.keys(userConnections));
  });
});
export { app, server, io };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside model / userModel.js Here I am creating a mongoose model to register the user. To keep it simple, I have created a model with only username and email.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose';
import validator from 'validator';

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      required: [true, 'Email is required'],
      unique: true,
      validate: {
        validator: validator.isEmail,
        message: 'Please enter a valid email',
      },
    },

    username: {
      type: String,
      required: [true, 'Username is required'],
      minlength: [3, 'Username must be at least 3 characters'],
    },
  },
  {
    timestamps: true,
  }
);
const User = mongoose.model('User', userSchema);
export default User;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside controller / userController.js This is where the user register and all user-related logics are written.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import User from '../model/userModel.js';

export const register = async (req, res) =&amp;gt; {
  try {
    const { username, email } = req.body;
    if (!username || !email) {
      return res
        .status(401)
        .json({ message: 'All fields are required', success: false });
    }
    const userExistsEmail = await User.findOne({ email });

    if (userExistsEmail) {
      return res
        .status(401)
        .json({ message: 'User already exists', success: false });
    }

    const user = await User.create({
      username,
      email,
    });

    return res
      .status(201)
      .json({ message: 'User created successfully', success: true, user });
  } catch (error) {
    console.log(error);
  }
};
export const allUsers = async (req, res) =&amp;gt; {
  try {
    const users = await User.find({});
    return res
      .status(200)
      .json({ message: 'Users fetched successfully', success: true, users });
  } catch (error) {
    console.log(error);
    return res.status(500).json({ message: 'Internal server error' });
  }
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside route / userRoute.js all the user routes are written. Since I'm only using sockets to see how many users are online, there are just 2 routes here, you can add more routes if you want.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import { allUsers, register } from '../controller/userController.js';

const router = express.Router();
router.post('/register', register);
router.get('/all', allUsers);

export default router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside config / db.js here is the function to connect the mongoose database.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose';
const connectDB = async () =&amp;gt; {
  try {
    const conn = await mongoose.connect(process.env.MONGO_URI);
    console.log(`MongoDB connected: ${conn.connection.host}`);
  } catch (error) {
    console.error(`Error: ${error.message}`);
    process.exit(1);
  }
};
export default connectDB;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside.env contains port numbers, client URLs, and database URIs for use in different files.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGO_URI=mongodb+srv://yourdbusername:password@cluster0.dfl8qwc.mongodb.net/socketio?retryWrites=true&amp;amp;w=majority&amp;amp;appName=Cluster0
PORT=5000
CLIENT_URL=http://localhost:5173
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Front end:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ..
cd client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create VIte and setup tailwind:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest
npm i axios for data fetching from backend
npm i socket.io-client for initialize socket in fontend
npm install tailwindcss @tailwindcss/vite  for styling UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside vite.config.js
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
  plugins: [react(), tailwindcss()],
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inside index.css
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import "tailwindcss";
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now inside components folder write Home.jsx file. There are two jobs here. One is to send the data to the server and the other is to render here if there is a user and also show how many online users are there. To see the online users, you have to match the ID of each user using the find method with the online user array.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from 'react';
import axios from 'axios';
const Home = ({ userInfo, setUser, onlineUsers }) =&amp;gt; {
  const [formData, setFormData] = useState({ email: '', username: '' });
  const [users, setUsers] = useState([]);

  const handleChange = (e) =&amp;gt; {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    const res = await axios.post(
      'http://localhost:5000/api/users/register',
      formData
    );
    if (res?.data?.success) {
      localStorage.setItem('user', JSON.stringify(res.data.user));
      setUser(res.data.user);
      fetchAllUsers();
    }
  };
  useEffect(() =&amp;gt; {
    fetchAllUsers();
  }, [onlineUsers]);
  const fetchAllUsers = async () =&amp;gt; {
    try {
      const response = await axios.get('http://localhost:5000/api/users/all');
      setUsers(response?.data?.users);
    } catch (error) {
      console.error('Error fetching users:', error);
    }
  };

  if (userInfo) {
    return (
      &amp;lt;div className='min-h-screen flex items-center justify-center bg-gradient-to-r from-gray-800 to-black text-white'&amp;gt;
        &amp;lt;div className='bg-gray-900 rounded-xl p-8 shadow-lg w-[90%] max-w-md text-center'&amp;gt;
          &amp;lt;h1 className='text-3xl font-bold mb-4'&amp;gt;
            Welcome, {userInfo.username} 👋
          &amp;lt;/h1&amp;gt;
          &amp;lt;div className='mt-10 text-left'&amp;gt;
            &amp;lt;h2 className='text-xl font-semibold mb-4'&amp;gt;All Users&amp;lt;/h2&amp;gt;
            &amp;lt;ul className='space-y-3'&amp;gt;
              {users.map((u, index) =&amp;gt; {
                const isOnline = onlineUsers.find(
                  (onlineUser) =&amp;gt; onlineUser === u._id
                );
                return (
                  &amp;lt;li
                    key={index}
                    className='flex items-center justify-between bg-gray-800 p-3 rounded-lg'
                  &amp;gt;
                    &amp;lt;div&amp;gt;
                      &amp;lt;p className='font-medium'&amp;gt;{u.username}&amp;lt;/p&amp;gt;
                      &amp;lt;p className='text-sm text-gray-400'&amp;gt;{u.email}&amp;lt;/p&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;span
                      className={`w-3 h-3 rounded-full ${
                        isOnline ? 'bg-green-400' : 'bg-gray-500'
                      }`}
                      title={isOnline ? 'Online' : 'Offline'}
                    /&amp;gt;
                  &amp;lt;/li&amp;gt;
                );
              })}
            &amp;lt;/ul&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }

  return (
    &amp;lt;div className='min-h-screen flex items-center justify-center bg-gradient-to-r from-gray-800 to-black text-white'&amp;gt;
      &amp;lt;div className='bg-gray-900 rounded-xl p-8 shadow-lg w-[90%] max-w-md'&amp;gt;
        &amp;lt;h2 className='text-2xl font-bold mb-6 text-center'&amp;gt;Register&amp;lt;/h2&amp;gt;
        &amp;lt;form onSubmit={handleSubmit} className='space-y-4'&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;label htmlFor='username' className='block text-sm mb-1'&amp;gt;
              Username
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type='text'
              name='username'
              id='username'
              value={formData.username}
              onChange={handleChange}
              required
              className='w-full px-4 py-2 rounded bg-gray-800 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-green-400'
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;label htmlFor='email' className='block text-sm mb-1'&amp;gt;
              Email
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type='email'
              name='email'
              id='email'
              value={formData.email}
              onChange={handleChange}
              required
              className='w-full px-4 py-2 rounded bg-gray-800 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-green-400'
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button
            type='submit'
            className='w-full bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded transition-all'
          &amp;gt;
            Register
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Home;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;inside the src folder create a file named App.jsx and write the following code. This is where the socket is actually initialized in the frontend. At the same time it checks from localStorage whether a user exists. If a user exists then The user data is passed to the home page using props. After the socket is initialized, the real time event getOnlineUsers which was created on the server is received here. You can receive any event inside socket.on if you want. Here, getOnlineUsers returns an array in which the online users id is stored. With the help of this ID, you can find out who is online.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react';
import './App.css';
import Home from './components/Home';
import { io } from 'socket.io-client';

function App() {
  const [user, setUser] = useState(() =&amp;gt; {
    const stored = localStorage.getItem('user');
    return stored ? JSON.parse(stored) : null;
  });
  const [onlineUsers, setOnlineUsers] = useState([]);
  useEffect(() =&amp;gt; {
    if (user) {
      const sock = io('http://localhost:5000', {
        query: { userId: user?._id },
        transports: ['websocket'],
      });
      sock.on('getOnlineUsers', (onlineUsers) =&amp;gt; {
        setOnlineUsers(onlineUsers);
      });

      return () =&amp;gt; {
        sock.close();
      };
    }
  }, [user]);
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Home userInfo={user} setUser={setUser} onlineUsers={onlineUsers} /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create many real time update related applications using socket.IO. Today, I have only shown how socket.IO can be used in a MERN stack application. You can add more if you want, such as receiving and sending user messages in a chat application , social media reactions etc.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>socket</category>
      <category>node</category>
      <category>react</category>
    </item>
  </channel>
</rss>
