How to use Socket.IO in Node.js

Real-time bidirectional communication requires WebSockets, but handling browser compatibility and reconnection logic manually is complex. With over 12 years of Node.js development experience since 2014 and as the creator of CoreUI, I’ve built numerous real-time features with Socket.IO. Socket.IO is a library that provides WebSocket functionality with automatic fallbacks, reconnection, and room-based broadcasting. This approach simplifies real-time communication compared to native WebSockets while adding powerful features like namespaces and middleware.

Use Socket.IO to create real-time servers with WebSocket connections and automatic fallback support.

npm install socket.io

Create Socket.IO server:

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

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

// Handle connections
io.on('connection', (socket) => {
  console.log('User connected:', socket.id)

  // Listen for custom events
  socket.on('message', (data) => {
    console.log('Message received:', data)

    // Emit to all clients
    io.emit('message', {
      id: socket.id,
      text: data.text,
      timestamp: Date.now()
    })
  })

  // Join a room
  socket.on('join-room', (roomName) => {
    socket.join(roomName)
    console.log(`${socket.id} joined room: ${roomName}`)

    // Emit to room
    io.to(roomName).emit('user-joined', {
      userId: socket.id,
      room: roomName
    })
  })

  // Emit to specific room
  socket.on('room-message', (data) => {
    io.to(data.room).emit('message', {
      id: socket.id,
      text: data.text,
      room: data.room
    })
  })

  // Private message
  socket.on('private-message', (data) => {
    socket.to(data.recipientId).emit('private-message', {
      from: socket.id,
      text: data.text
    })
  })

  // Broadcast (to all except sender)
  socket.on('broadcast', (data) => {
    socket.broadcast.emit('broadcast', data)
  })

  // Handle disconnect
  socket.on('disconnect', () => {
    console.log('User disconnected:', socket.id)
  })
})

server.listen(3000, () => {
  console.log('Socket.IO server running on port 3000')
})

Client-side usage:

const socket = io('http://localhost:3000')

// Connect event
socket.on('connect', () => {
  console.log('Connected:', socket.id)
})

// Listen for messages
socket.on('message', (data) => {
  console.log('Message:', data)
  displayMessage(data)
})

// Send message
function sendMessage(text) {
  socket.emit('message', { text })
}

// Join room
socket.emit('join-room', 'general')

// Send room message
socket.emit('room-message', {
  room: 'general',
  text: 'Hello room'
})

// Handle disconnect
socket.on('disconnect', () => {
  console.log('Disconnected')
})

With namespaces:

// Server
const adminNamespace = io.of('/admin')

adminNamespace.on('connection', (socket) => {
  console.log('Admin connected')

  socket.on('admin-action', (data) => {
    adminNamespace.emit('admin-update', data)
  })
})

// Client
const adminSocket = io('http://localhost:3000/admin')

Best Practice Note

Socket.IO automatically handles reconnection with exponential backoff. Use rooms for efficient broadcasting to specific user groups. Namespaces provide complete separation of concerns for different parts of your application. Add middleware for authentication before allowing connections. Use acknowledgments for confirmation that messages were received. Socket.IO falls back to long-polling if WebSockets aren’t available. This is how we build real-time features in CoreUI dashboards—using Socket.IO for reliable bidirectional communication with automatic fallbacks and efficient room-based broadcasting.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Open All Links in New Tab Using JavaScript
How to Open All Links in New Tab Using JavaScript

JavaScript printf equivalent
JavaScript printf equivalent

Maintaining Accessibility with React createPortal and aria-owns: A Complete Guide
Maintaining Accessibility with React createPortal and aria-owns: A Complete Guide

CSS Selector for Parent Element
CSS Selector for Parent Element

Answers by CoreUI Core Team