Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nodejs/undici/llms.txt

Use this file to discover all available pages before exploring further.

undici exports a WebSocket class that implements the WHATWG WebSocket API, enabling bidirectional communication from Node.js without browser restrictions. It also exports an experimental WebSocketStream for stream-based WebSocket access and a ping() utility for keepalive frames.

WebSocket

Constructor

new WebSocket(url[, protocol])
url
string | URL
required
The WebSocket server URL. Must use ws:// or wss:// scheme.
protocol
string | string[] | WebSocketInit
Optional. A subprotocol string, array of subprotocols, or a WebSocketInit object for advanced configuration.

WebSocketInit options

When passing an object as the second argument:
protocols
string | string[]
Subprotocol(s) to request the server use.
dispatcher
Dispatcher
A custom dispatcher (e.g. ProxyAgent, Agent) to use for the WebSocket handshake connection.
headers
HeadersInit
Custom headers to include in the WebSocket handshake HTTP request.

Basic usage

Basic WebSocket connection
import { WebSocket } from 'undici'

const ws = new WebSocket('wss://echo.websocket.events')

ws.onopen = () => {
  console.log('Connected')
  ws.send('Hello, server!')
}

ws.onmessage = (event) => {
  console.log('Received:', event.data)
}

ws.onerror = (event) => {
  console.error('WebSocket error:', event)
}

ws.onclose = (event) => {
  console.log('Closed:', event.code, event.reason)
}

Using a custom dispatcher

Pass a WebSocketInit object to use a custom dispatcher such as ProxyAgent:
WebSocket through a proxy
import { WebSocket, ProxyAgent } from 'undici'

const proxyAgent = new ProxyAgent('http://my.proxy.server:8080')

const ws = new WebSocket('wss://echo.websocket.events', {
  dispatcher: proxyAgent,
  protocols: ['echo', 'chat'],
  headers: { 'x-custom-header': 'value' }
})
The WebSocketInit object form is a Node.js extension — it will not work in browsers or other platforms that don’t allow passing an object as the second argument.

Subprotocols (standard form)

If you don’t need a custom dispatcher, use the standard string/array form:
import { WebSocket } from 'undici'

const ws = new WebSocket('wss://echo.websocket.events', ['echo', 'chat'])

WebSocket over HTTP/2

WebSocket over HTTP/2 is experimental and likely to change in a future version.
WebSocket over HTTP/2
import { Agent, WebSocket } from 'undici'

const agent = new Agent({ allowH2: true })

const ws = new WebSocket('wss://echo.websocket.events', {
  dispatcher: agent,
  protocols: ['echo', 'chat']
})

Sending data

Sending text and binary
import { WebSocket } from 'undici'

const ws = new WebSocket('wss://echo.websocket.events')

ws.onopen = () => {
  // Send text
  ws.send('Hello, world!')

  // Send binary (ArrayBuffer)
  const buffer = new ArrayBuffer(8)
  ws.send(buffer)

  // Send binary (Uint8Array)
  const bytes = new Uint8Array([1, 2, 3, 4])
  ws.send(bytes)
}

Receiving binary data

Set binaryType to control how binary messages are delivered:
ws.binaryType = 'arraybuffer' // default: 'blob'

ws.onmessage = (event) => {
  if (event.data instanceof ArrayBuffer) {
    const view = new Uint8Array(event.data)
    console.log('Binary data:', view)
  }
}

readyState constants

ConstantValueDescription
WebSocket.CONNECTING0Connection not yet established
WebSocket.OPEN1Connection is open and ready
WebSocket.CLOSING2Connection is closing
WebSocket.CLOSED3Connection is closed

Closing connections

// Graceful close with code and reason
ws.close(1000, 'Normal closure')

// Close codes: 1000 (normal), 1001 (going away), 1008 (policy violation), etc.

ping()

The ping() function sends a WebSocket ping frame for keepalive or connection verification.
ping(websocket[, payload])
websocket
WebSocket
required
The WebSocket instance to send the ping frame on.
payload
Buffer | undefined
Optional payload data. Must not exceed 125 bytes. The server must respond with a pong containing the same payload.
Using ping for keepalive
import { WebSocket, ping } from 'undici'

const ws = new WebSocket('wss://echo.websocket.events')

ws.addEventListener('open', () => {
  // Ping with no payload
  ping(ws)

  // Ping with payload
  const payload = Buffer.from('keepalive')
  ping(ws, payload)
})

// Keepalive interval
const interval = setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ping(ws)
  }
}, 30_000)

ws.addEventListener('close', () => clearInterval(interval))
ping() only sends if the WebSocket is in the OPEN state. Payloads must not exceed 125 bytes.

WebSocketStream

WebSocketStream is experimental and the API has not been finalized. It is likely to change in future versions.
WebSocketStream provides a stream-based interface to WebSocket connections using WHATWG Streams (readable/writable).
import { WebSocketStream } from 'undici'

const stream = new WebSocketStream('wss://echo.websocket.org/')
const { readable, writable } = await stream.opened

async function read() {
  const reader = readable.getReader()
  while (true) {
    const { done, value } = await reader.read()
    if (done) break
    console.log('Received:', value)
  }
}

async function write() {
  const writer = writable.getWriter()
  writer.write('Hello, world!')
  writer.releaseLock()
}

read()
setInterval(() => write(), 5000)
See MDN WebSocketStream for the full API specification.

Build docs developers (and LLMs) love