Skip to main content
Version: 3.x

Custom parser

Since Socket.IO v2.0.0, it is now possible to provide your own parser, in order to control the marshalling / unmarshalling of packets.


const httpServer = require("http").createServer();const io = require("")(httpServer, {  parser: myParser});


const socket = io({  parser: myParser});

Implementing your own parser#

Here is a basic example with a parser that uses the JSON.stringify() and JSON.parse() methods:

const Emitter = require("component-emitter"); // polyfill of Node.js EventEmitter in the browser 
class Encoder {  /**   * Encode a packet into a list of strings/buffers   */  encode(packet) {    return [JSON.stringify(packet)];  }}
class Decoder extends Emitter {  /**   * Receive a chunk (string or buffer) and optionally emit a "decoded" event with the reconstructed packet   */  add(chunk) {    const packet = JSON.parse(chunk);    if (this.isPacketValid(packet)) {      this.emit("decoded", packet);    } else {      throw new Error("invalid format");    }  }  isPacketValid({ type, data, nsp, id }) {    const isNamespaceValid = typeof nsp === "string";    const isAckIdValid = id === undefined || Number.isInteger(id);    if (!isNamespaceValid || !isAckIdValid) {      return false;    }    switch (type) {      case 0: // CONNECT        return data === undefined || typeof data === "object";      case 1: // DISCONNECT        return data === undefined;      case 2: // EVENT        return Array.isArray(data) && data.length > 0;      case 3: // ACK        return Array.isArray(data);      case 4: // CONNECT_ERROR        return typeof data === "object";      default:        return false;    }  }  /**   * Clean up internal buffers   */  destroy() {}}
module.exports = { Encoder, Decoder };

The default parser#

The source code of the default parser (the package) can be found here:

Example of output:

  • basic emit
socket.emit("test", 42);

will be encoded as:

2["test",42]|||โ””โ”€ JSON-encoded payloadโ””โ”€ packet type (2 => EVENT)
  • emit with binary, acknowledgement and custom namespace
socket.emit("test", Uint8Array.from([42]), () => {  console.log("ack received");});

will be encoded as:

51-/admin,13["test",{"_placeholder":true,"num":0}]||||     || โ””โ”€ JSON-encoded payload with placeholders for binary attachments||||     |โ””โ”€ acknowledgement id||||     โ””โ”€ separator|||โ””โ”€ namespace (not included when it's the main namespace)||โ””โ”€ separator|โ””โ”€ number of binary attachmentsโ””โ”€ packet type (5 => BINARY EVENT)
and an additional attachment (the extracted Uint8Array)



  • packets with binary content are sent as two distinct WebSocket frames (if the WebSocket connection is established)

The msgpack parser#

This parser uses the MessagePack serialization format.

The source code of this parser can be found here:

Sample usage:


const httpServer = require("http").createServer();const io = require("")(httpServer, {  parser: require("")});

Client (Node.js)

const socket = require("")("", {  parser: require("")});

In the browser, there is now an official bundle which includes this parser:

In that case, you don't need to specify the parser option.


  • packets with binary content are sent as one single WebSocket frame (if the WebSocket connection is established)
  • may results in smaller payloads (especially when using a lot of numbers)


Please note that relies on the MessagePack implementation. This implementation mainly focuses on performance and minimal bundle size, and thus does not support features like extension types. For a parser based on the official JavaScript implementation, please check this package.