Fast encoder and decoder for the Erlang Term Format (version 131) for JavaScript
npx @tessl/cli install tessl/npm-erlpack@0.1.0Erlpack is a fast encoder and decoder for the Erlang Term Format (ETF) version 131 for JavaScript. It provides a native implementation for high-performance encoding and decoding of data structures compatible with Erlang and Elixir systems, making it ideal for applications that need to communicate with Erlang/Elixir services or implement protocols like Discord's gateway.
npm install erlpackconst erlpack = require('erlpack');For ES modules:
import * as erlpack from 'erlpack';const erlpack = require('erlpack');
// Encoding JavaScript data to ETF binary format
const data = {
user: 'alice',
age: 25,
active: true,
tags: ['admin', 'user'],
score: 98.5
};
const packed = erlpack.pack(data);
console.log(packed); // Buffer containing ETF binary data
// Decoding ETF binary data back to JavaScript
const unpacked = erlpack.unpack(packed);
console.log(unpacked); // Original JavaScript objectEncodes JavaScript data structures into Erlang Term Format (ETF) version 131 binary format.
/**
* Encodes JavaScript data structures into ETF binary format
* @param {any} data - JavaScript value to encode
* @returns {Buffer} Buffer containing ETF-encoded binary data
* @throws {Error} "Out of memory" when insufficient memory
* @throws {Error} "Unknown error" for other encoding failures
*/
function pack(data) {}Supported JavaScript Types:
null, undefined → ETF nil atomtrue, false → ETF true/false atomsstring → ETF binary/stringnumber (0-255) → ETF small integernumber (int32 range) → ETF integernumber (float) → ETF new floatobject → ETF map/dictionaryarray → ETF list[] (empty array) → ETF nil listUsage Examples:
// Basic data types
erlpack.pack(null); // nil atom
erlpack.pack(true); // true atom
erlpack.pack(false); // false atom
erlpack.pack("hello"); // binary string
erlpack.pack(42); // integer
erlpack.pack(3.14); // float
// Complex structures
erlpack.pack({
name: "Alice",
age: 30,
hobbies: ["reading", "coding"]
});
erlpack.pack([1, "two", 3.0, true, null]);Decodes ETF binary data back into JavaScript data structures.
/**
* Decodes ETF binary data into JavaScript data structures
* @param {Buffer|Uint8Array} data - ETF-encoded binary data to decode
* @returns {any} Decoded JavaScript value
* @throws {Error} "Attempting to unpack a non-object." when data is not Buffer/Uint8Array
* @throws {Error} "Zero length buffer." when buffer is empty
* @throws {Error} "Unsupported erlang term type identifier found" for unknown ETF types
* @throws {Error} "Reading beyond the end of the buffer" for malformed data
* @throws {Error} "Reading a byte passes the end of the buffer." for single byte read errors
* @throws {Error} "Reading two bytes passes the end of the buffer." for double byte read errors
* @throws {Error} "Reading three bytes passes the end of the buffer." for triple byte read errors
* @throws {Error} "Reading sequence past the end of the buffer." for sequence read errors
* @throws {Error} "Unpacking beyond the end of the buffer" for general unpacking errors
* @throws {Error} "Unable to decode big ints larger than 8 bytes" for oversized integers
*/
function unpack(data) {}Supported ETF Types:
nullbooleanstringstringnumbernumbernumbernumberstringarray[]objectarray{node: string, id: number[], creation: number}{node: string, id: number, creation: number}{node: string, id: number, serial: number, creation: number}{mod: string, fun: string, arity: number}Usage Examples:
// Decode from Buffer
const buffer = Buffer.from('\\x83m\\x00\\x00\\x00\\x05hello', 'binary');
erlpack.unpack(buffer); // "hello"
// Decode from Uint8Array
const uint8Array = new Uint8Array([0x83, 0x6a]); // ETF nil list
erlpack.unpack(uint8Array); // []
// Handle complex structures
const complexBuffer = Buffer.from('\\x83t\\x00\\x00\\x00\\x01m\\x00\\x00\\x00\\x04namem\\x00\\x00\\x00\\x05Alice', 'binary');
erlpack.unpack(complexBuffer); // {name: "Alice"}Both pack and unpack functions throw exceptions for various error conditions:
Error Handling Example:
try {
const packed = erlpack.pack(data);
const unpacked = erlpack.unpack(packed);
} catch (error) {
console.error('ETF operation failed:', error.message);
// Handle specific error types based on error.message
}When using erlpack in Electron applications, you may need to convert blink::WebArrayBuffer to Node.js Buffer before unpacking. See the project README for native code examples if this conversion is needed in your environment.