Setting up notification system design with socet.io

Written by Fredcode


Back when i started to code newly I'd have anxiety and the feeling I'm not good enough

when I'd write simple webapps i always ducked implementing a notification feature to my apps because i thought they were really complex and that i wasn’t ready yet. so one day i gathered enough courage to figure how to actually implement this cool feature and i did it , let me tell it way easier than i thought , PS: this was probably 10 years ago in school.


well now In today’s fast-paced digital world, real-time notifications have become a crucial part of many web applications. Whether you’re building a chat application, an e-commerce site, or a SaaS platform, providing users with instant updates enhances engagement and improves the overall user experience. One of the most effective ways to implement real-time notifications is by using Socket.IO. In this blog, we’ll walk you through the process of setting up a notification system with Socket.IO


Why Choose Socket.IO?

Socket.IO is a JavaScript library that enables real-time and event-based communication between the browser and the server. It is built on top of WebSockets, but it offers additional features such as fallback to other protocols when WebSockets are not available, automatic reconnection, and more. This makes Socket.IO a robust choice for building real-time applications, including notification systems.


Prerequisites

Before we dive into the implementation, make sure you have the following installed on your machine:

  • Node.js
  • npm
  • Basic understanding of Express.js (for setting up the server)
  • Basic understanding of React.js or any frontend framework (for client-side implementation)

ps: i will be using one of projects i implemented socket.io to explain in the rest of this blog

https://github.dev/fredcodee/TeamManagement



Install socket.io

npm install socket.io



create server

create a socket.js file in a configs folder

const socketIo = require('socket.io');

module.exports = (server) => {
  const io = socketIo(server, {
    cors: {
      origin:[process.env.FRONTEND_ORIGIN_DEV , process.env.FRONTEND_ORIGIN_PROD ],
      methods: ["GET", "POST"]
    }
  });

  io.on('connection', (socket) => {
    console.log('socket connected');

    socket.on('disconnect', () => {
      console.log('socket disconnected');
    });
  });

  return io;
};

The code snippet defines a function that sets up a Socket.IO server for real-time communication with a React application. It configures CORS to allow connections from specific origins, handles socket connections and disconnections, and returns the Socket.IO server instance for use in other parts of the Node.js application


then in your app.js/server.js

const config = require('./configs/config');
const app = require('./configs/express');
const http = require('http');
require('./configs/mongoose');

const server = http.createServer(app);
const io = require('./configs/socket')(server);
app.set('io', io); // set io object to app (socket.io set up)

server.listen(config.port, () => {
    console.info(`server started on port ${config.port}`);
  });
  
module.exports = { server };

  • const io = require('./configs/socket')(server);: Imports a function (socket) from the configs/socket.js file. This function likely creates a Socket.IO server instance and configures it. It's passed the server object to integrate Socket.IO with the existing HTTP server.
  • app.set('io', io); // set io object to app (socket.io set up): Sets the imported Socket.IO server instance (io) as a property named io on the Express application (app). This allows other parts of the Express app to access and use the Socket.IO server for real-time communication.


now in models

i have NotificationModel.js file

it just defines a Mongoose schema and model for storing notification data in a MongoDB database. It includes fields for user association, notification message, read status, creation time, an optional link, and organization association. The exported Notification model allows you to interact with notification data in your Node.js application.

const mongoose = require('mongoose')
const notificationSchema = new mongoose.Schema({
    user_id: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    notification: {
        type: String,
        required: true,
    },
    read: {
        type: Boolean,
        default: false
    },
    created_at: {
        type: Date,
        default: Date.now
    },
    link: {
        type: String,
        default: null
    } ,
    organization_id:{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Organization'
    }
})
const Notification = mongoose.model('Notification', notificationSchema)
module.exports = Notification


Why you may ask?

This structure allows applications to efficiently manage and track notifications, enhancing user experience, enabling features like messaging and alerts, and providing a foundation for data analysis. The schema includes fields for user association, notification message, read status, creation time, an optional link, and organization association. This flexibility allows for customization to suit specific application requirements. By using this model, developers can effectively handle notification data within their Node.js applications.


So how do i set it up to alert or real time communication my app logic?

for eg in my appService.js file

full source code : https://github.dev/fredcodee/TeamManagement

async function addNotificationToDbSingle(req, userId, teamId, notificationMessage, notificationLink) {
    try {
        const notification = new Notification({
            user_id: userId,
            teamId: teamId,
            notification: notificationMessage,
            link: notificationLink || null
        }
        );
        await notification.save();

        const io = req.app.get('io'); // get io object from app
        const alertData = {
            userId: notification.user_id,
            notification: notification.notification,
            link: notification.link
        }
        await io.emit('Notification', alertData);
        return true;
    } catch (error) {
        throw new Error(`Cant add notification to db ${error}`);
    }
}


Retrieving Socket.IO Server Instance:

const io = req.app.get('io'); // get io object from app

  • This retrieves the Socket.IO server instance (io) stored on the Express application object (req.app). This was likely set up in another part of your application (e.g., the main entry point) to integrate Socket.IO with your Express app.


Preparing Notification Data for Broadcast:

const alertData = { userId: notification.user_id, notification: notification.notification, link: notification.link };

  • This creates a new object named alertData containing only the necessary information for the notification: userId, notification message, and link.


Emitting Socket.IO Event:

await io.emit('Notification', alertData);

  • This line uses the io object to emit a real-time event named "Notification" with the alertData object as the payload. Any clients (presumably your React application) connected to the Socket.IO server and listening for this event will receive the notification data.



and vola!,

remember you will still have to configure your frontend to be able to receive data omitted from socket in the backed the configuration varies on what frontend stack you use



Conclusion

Setting up a notification system with Socket.IO is a powerful way to deliver real-time updates to your users. By following this guide, you’ve learned how to create a basic notification system, enhance it with user-specific notifications, and even store notifications in a database for persistence.

Socket.IO’s flexibility and ease of use make it a great choice for building real-time features in your web applications. Whether you’re working on a small project or a large-scale application, this setup will provide a solid foundation for implementing a robust notification system.

Happy coding!

Share this blog post with your friends

@Fredcode 2025. All rights reserved.