One data grid for JavaScript, React, Vue & Angular. Sorting, filtering, virtualization, pinning, and CSV export included. Early access $199 $349 → [Get it now]

How to build a chat app with WebSockets in Node.js

Real-time chat applications require bidirectional communication where the server can push messages to clients instantly without polling. As the creator of CoreUI, I’ve built numerous real-time applications with WebSockets. WebSockets provide full-duplex communication channels over a single TCP connection, perfect for chat, notifications, and live updates. The native ws library offers a lightweight WebSocket implementation for Node.js without the overhead of frameworks.

Use the ws library to create a WebSocket server that broadcasts messages to all connected clients.

npm install ws

Create WebSocket chat server:

const WebSocket = require('ws')
const http = require('http')

const server = http.createServer()
const wss = new WebSocket.Server({ server })

const clients = new Set()

wss.on('connection', (ws) => {
  console.log('New client connected')
  clients.add(ws)

  // Send welcome message
  ws.send(JSON.stringify({
    type: 'system',
    message: 'Welcome to the chat!',
    timestamp: new Date().toISOString()
  }))

  // Broadcast user joined
  broadcast({
    type: 'system',
    message: 'A user joined the chat',
    timestamp: new Date().toISOString()
  }, ws)

  // Handle incoming messages
  ws.on('message', (data) => {
    try {
      const message = JSON.parse(data)

      // Broadcast to all clients
      broadcast({
        type: 'message',
        user: message.user || 'Anonymous',
        text: message.text,
        timestamp: new Date().toISOString()
      })
    } catch (error) {
      console.error('Error parsing message:', error)
    }
  })

  // Handle disconnect
  ws.on('close', () => {
    console.log('Client disconnected')
    clients.delete(ws)

    broadcast({
      type: 'system',
      message: 'A user left the chat',
      timestamp: new Date().toISOString()
    })
  })

  ws.on('error', (error) => {
    console.error('WebSocket error:', error)
    clients.delete(ws)
  })
})

function broadcast(data, exclude = null) {
  const message = JSON.stringify(data)

  clients.forEach(client => {
    if (client !== exclude && client.readyState === WebSocket.OPEN) {
      client.send(message)
    }
  })
}

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

Client-side JavaScript:

const ws = new WebSocket('ws://localhost:3000')

ws.onopen = () => {
  console.log('Connected to chat server')
}

ws.onmessage = (event) => {
  const data = JSON.parse(event.data)
  displayMessage(data)
}

function sendMessage(text) {
  ws.send(JSON.stringify({
    user: 'John',
    text: text
  }))
}

function displayMessage(data) {
  console.log(`[${data.timestamp}] ${data.user}: ${data.text}`)
}

Best Practice Note

Always validate and sanitize incoming messages to prevent XSS attacks. Track connected clients in a Set for efficient broadcasts. Check readyState === WebSocket.OPEN before sending to avoid errors. Implement heartbeat/ping-pong to detect dead connections. For production, add user authentication, message persistence, and rate limiting. Consider Socket.IO for broader browser support and automatic fallbacks. This is how we build real-time features in CoreUI backends—using native WebSockets for performance with proper error handling and connection management.


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.
What is the difference between typeof and instanceof in JavaScript
What is the difference between typeof and instanceof in JavaScript

How to conditionally add attributes to React components
How to conditionally add attributes to React components

How to force a React component to re-render
How to force a React component to re-render

What are the three dots `...` in JavaScript do?
What are the three dots `...` in JavaScript do?

Answers by CoreUI Core Team