{"id":10597,"library":"bser","title":"BSER Binary Serialization","description":"BSER (Binary Serialization) is a compact, framed binary serialization scheme designed as an alternative to JSON, primarily for local Inter-Process Communication (IPC). It is part of the larger Watchman project by Facebook (Meta Platforms, Inc.), which implies its development is active and closely tied to Watchman's needs. While the npm package version is 2.1.1, the upstream Watchman project sees rapid, often weekly, releases in a `vYYYY.MM.DD.00` format, indicating continuous development and updates. BSER differentiates itself with framed encoding for streaming sequences of values, treating strings as binary without specific character encoding (matching OS filename conventions), making it efficient for specific low-level IPC scenarios. It offers both synchronous (`loadFromBuffer`, `dumpToBuffer`) and asynchronous (`BunserBuf` for event-driven decoding) APIs.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/facebook/watchman","tags":["javascript","bser","binary","protocol"],"install":[{"cmd":"npm install bser","lang":"bash","label":"npm"},{"cmd":"yarn add bser","lang":"bash","label":"yarn"},{"cmd":"pnpm add bser","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The 'bser' package is primarily a CommonJS module. Direct ES Module 'import' statements may not work as expected or require specific bundler configurations without explicit 'exports' map in package.json.","wrong":"import * as bser from 'bser';","symbol":"bser","correct":"const bser = require('bser');"},{"note":"While CommonJS allows destructuring, the package is predominantly consumed by importing the entire module object first. Attempting named ESM imports may fail.","wrong":"import { loadFromBuffer } from 'bser';","symbol":"loadFromBuffer","correct":"const { loadFromBuffer } = require('bser');"},{"note":"BunserBuf is a class exported as a property of the main 'bser' module object, not a direct named export from the module root in CommonJS. ESM import attempts may not correctly resolve it.","wrong":"import { BunserBuf } from 'bser';","symbol":"BunserBuf","correct":"const BunserBuf = require('bser').BunserBuf;"}],"quickstart":{"code":"const net = require('net');\nconst bser = require('bser');\n\n// Simulate a socket server\nconst server = net.createServer(socket => {\n  console.log('Client connected.');\n\n  const bunser = new bser.BunserBuf();\n\n  bunser.on('value', obj => {\n    console.log('Server received (decoded):', obj);\n    // Echo back a response\n    const response = bser.dumpToBuffer(['pong', obj[1]]);\n    socket.write(response);\n  });\n\n  socket.on('data', buf => {\n    bunser.append(buf);\n  });\n\n  socket.on('end', () => {\n    console.log('Client disconnected.');\n  });\n\n  socket.on('error', err => {\n    console.error('Server socket error:', err);\n  });\n});\n\nconst SOCKET_PATH = '/tmp/bser-socket';\nserver.listen(SOCKET_PATH, () => {\n  console.log(`Server listening on ${SOCKET_PATH}`);\n\n  // Simulate a client\n  const client = net.connect(SOCKET_PATH, () => {\n    console.log('Client connected to server.');\n    const payload = ['hello', 'world', 123];\n    const encoded = bser.dumpToBuffer(payload);\n    console.log('Client sending (encoded):', encoded);\n    client.write(encoded);\n\n    const clientBunser = new bser.BunserBuf();\n    clientBunser.on('value', obj => {\n      console.log('Client received (decoded):', obj);\n      client.end(); // End client after receiving response\n    });\n    client.on('data', buf => {\n      clientBunser.append(buf);\n    });\n\n    client.on('error', err => {\n      console.error('Client socket error:', err);\n    });\n  });\n\n  client.on('end', () => {\n    console.log('Client disconnected. Server closing.');\n    server.close();\n  });\n});","lang":"javascript","description":"Demonstrates basic synchronous BSER encoding (`dumpToBuffer`) and asynchronous decoding (`BunserBuf`) for IPC over a Unix domain socket, including event handling for streamed data."},"warnings":[{"fix":"For potentially large or streaming data, prefer the asynchronous `BunserBuf` API, which processes data incrementally and emits 'value' events, preventing event loop blocking.","message":"The `bser.loadFromBuffer` and `bser.dumpToBuffer` APIs are synchronous. While suitable for small IPC payloads, using them with very large buffers can block the Node.js event loop, leading to performance bottlenecks and unresponsiveness in high-throughput applications.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Always wrap calls to `bser.loadFromBuffer` in a `try...catch` block to handle malformed BSER input gracefully, e.g., `try { const obj = bser.loadFromBuffer(buf); } catch (e) { console.error('BSER decode error:', e); }`.","message":"The `bser.loadFromBuffer` function throws an error directly if the input buffer is not a valid BSER stream. This requires explicit `try...catch` blocks for robust error handling to prevent application crashes.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Ensure you always register an event listener for the `'value'` event on `BunserBuf` instances, e.g., `bunser.on('value', (obj) => { /* process obj */ });`. Other events like `'error'` should also be handled.","message":"The `BunserBuf` API is entirely event-driven for asynchronous decoding. Data is not returned directly but emitted via the `'value'` event. Developers new to event emitters might overlook attaching this listener, resulting in data appearing to be 'lost' or not processed.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"In ESM projects, consider using a dynamic `import('bser').then(bser => { ... })` or consult bundler-specific configurations to handle CommonJS modules. If possible, stick to `require()` if your project largely remains CommonJS.","message":"The `bser` package is primarily distributed and documented as a CommonJS module using `require()`. While Node.js can sometimes interop with CommonJS modules from ESM, directly using `import { Name } from 'bser'` syntax in an ESM context might lead to unexpected `undefined` imports or runtime errors without specific `package.json` `exports` configurations (which are not explicitly provided by `bser`).","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Adhere to the intended use case for local IPC. For network communication or data exchange requiring specific character encodings, consider alternatives like JSON, Protocol Buffers, or custom protocols with defined encoding standards.","message":"BSER is explicitly 'intended to be used for local-IPC only' and its strings are 'represented as binary with no specific encoding'. This means it's not suitable for cross-platform or network communication where explicit character encoding (e.g., UTF-8) and network framing protocols are critical for interoperability and security.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the module is correctly imported in CommonJS: `const bser = require('bser');`. If in ESM, confirm your build system or Node.js environment correctly handles CommonJS module interop, or use `import bser from 'bser'` if it's a default export (less likely for this package).","cause":"Attempting to call `loadFromBuffer` on an `undefined` or improperly imported `bser` object, often due to incorrect CommonJS `require` or failed ESM `import` in a dual-module setup.","error":"TypeError: bser.loadFromBuffer is not a function"},{"fix":"Verify the source of the buffer data. Ensure the sending side is correctly encoding data using `bser.dumpToBuffer` and that no data corruption or truncation occurs during transmission. Implement `try...catch` around `loadFromBuffer` and `bunser.on('error', ...)` for `BunserBuf`.","cause":"The input `Buffer` provided to `bser.loadFromBuffer` or `bunser.append` does not conform to the BSER binary serialization format, indicating corrupted data or an incorrect protocol.","error":"Error: Invalid BSER buffer"},{"fix":"Always attach a listener to the `'value'` event of your `BunserBuf` instance: `bunser.on('value', function(obj) { console.log('Decoded object:', obj); });`. Also consider handling the `'error'` event for robustness.","cause":"The asynchronous `BunserBuf` is being used, but no listener has been attached to its `'value'` event, so decoded objects are emitted but not captured or processed.","error":"Data is not being processed from BunserBuf after `append` call"}],"ecosystem":"npm"}