npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

bobj

v2.0.0

Published

A modular JavaScript object serialization library.

Readme

Bobj - A modular JavaScript object serialization library

Introduction

Bobj is short for "Binary Object", and it is a lightweight, extensible JavaScript library designed to serialize JavaScript objects into a binary format (bobj) and deserialize bobj binary data back into JavaScript objects. It supports built-in data types (objects, arrays, Uint8Array, strings, numbers, booleans, null, and undefined) and provides a plugin system for custom data type handling.

Key Features

  • Multi-type Support: Serializes/deserializes common JavaScript primitives and objects.
  • Extensible Plugin System: Add support for custom data types via plugins.
  • Binary Format: Efficient binary representation for compact storage/transmission.

Installation

# Using pnpm
pnpm install bobj

# Using npm
npm install bobj

Basic Usage

Serialization (Object → bobj Binary)

import { Serializer } from "bobj";

// Define an object to serialize
const exampleObj = {
  name: "Bobj",
  version: 1.0,
  tags: ["serialization", "binary"],
  active: true,
  metadata: new Uint8Array([0x01, 0x02, 0x03]),
  nesting:{
    name: "Bobj",
    version: 1.0,
    tags: ["serialization", "binary"],
    active: true,
    metadata: new Uint8Array([0x01, 0x02, 0x03]),
  }
};

// Create a serializer instance
const serializer = new Serializer();

// Serialize the object to a Uint8Array (bobj format)
const bobjBinary = await serializer.serialize(exampleObj);
// Output: Uint8Array([...binary data...])

Deserialization (bobj Binary → Object)

import { Deserializer } from "bobj";

// Create a deserializer instance
const deserializer = new Deserializer();

// Deserialize the bobj binary back to an object
const restoredObj = await deserializer.deserialize(bobjBinary);
// Output: { name: "Bobj", version: 1.0, tags: ["serialization", "binary"], ... }

Plugin Example: Custom Data Type Support

Bobj’s plugin system allows you to extend serialization/deserialization for custom data types (e.g., Date, Set, or user-defined classes). Below is an example for handling Date objects.

Step 1: Create a Serialization Plugin

Add a plugin to serialize Date objects into timestamps (stored as 8-byte floats).

// date-serializer-plugin.ts
import type { SerializerPluginType } from "../types/serializer";
import { numberToU8i } from "../utils/number_u8i_converter";

const DateSerializerPlugin: SerializerPluginType<Date> = {
  // Filter: Check if the target is a Date
  filter: (target) => target instanceof Date,
  // Unique type identifier
  targetType: new TextEncoder().encode("Date"),
  // Serialize Date to a timestamp (8-byte float)
  serialize: ({ target }) => {
    const timestamp = target.getTime();
    return numberToU8i(timestamp); // Convert number to Uint8Array
  },
};

export default DateSerializerPlugin;

Step 2: Create a Deserialization Plugin

Add a plugin to deserialize 8-byte floats back into Date objects.

// date-deserializer-plugin.ts
import type { DeserializerPluginType } from "../types/deserializer";
import { u8iToNumber } from "../utils/number_u8i_converter";

const DateDeserializerPlugin: DeserializerPluginType<Date> = {
  // Filter: Check if the value type is "Date"
  filter: new TextEncoder().encode("Date"),
  // Deserialize Uint8Array to Date
  deserialize: ({ targetArray }) => {
    const timestamp = u8iToNumber(targetArray); // Convert Uint8Array to number
    return new Date(timestamp);
  },
};

export default DateDeserializerPlugin;

Step 3: Register Plugins

Register the plugins with the Serializer and Deserializer to enable custom handling.

import { Serializer, Deserializer } from "bobj";
import DateSerializerPlugin from "./date-serializer-plugin";
import DateDeserializerPlugin from "./date-deserializer-plugin";

// Initialize serializer with the Date plugin
const serializer = new Serializer();
serializer.registerPlugin(DateSerializerPlugin);

// Initialize deserializer with the Date plugin
const deserializer = new Deserializer();
deserializer.registerPlugin(DateDeserializerPlugin);

// Test with a Date object
const testDate = {date: new Date("2024-01-01")};
const dateBinary = await serializer.serialize(testDate); // Uint8Array([...timestamp bytes...])
const restoredDate = await deserializer.deserialize(dateBinary); // { date: Date("2024-01-01") }

Benchmark Comparison

The benchmark code is generated by AI

All tests were run 1000 times per case on bun, measuring average serialization/deserialization time (ms) and resulting data size (bytes).
For large Uint8Array objects, JSON and BSON are skipped due to their limitations.

| Case | Method | Serialize (ms) | Deserialize (ms) | Data Size (bytes) | |--------------------------------------------------|----------------------|----------------|------------------|-------------------| | Normal Object | bobj | 0.0240 | 0.0168 | 125 | | | bobj (sync) | 0.0152 | 0.0154 | 125 | | | bobj (fastU8iArr) | N/A | 0.0121 | N/A | | | JSON | 0.0011 | 0.0004 | 73 | | | BSON | 0.0044 | 0.0038 | 93 | | | msgpack | 0.0045 | 0.0030 | 46 | | Object with 1000 keys | bobj | 1.6406 | 1.1971 | 15890 | | | bobj (sync) | 1.6498 | 1.2041 | 15890 | | | bobj (fastU8iArr) | N/A | 1.2003 | N/A | | | JSON | 0.1188 | 0.0569 | 9781 | | | BSON | 0.1886 | 0.1586 | 8895 | | | msgpack | 0.1623 | 0.1867 | 6509 | | Large Uint8Array (10MB) | bobj | 1.7151 | 1.4187 | 10,485,771 | | | bobj (sync) | 1.6250 | 1.4469 | 10,485,771 | | | bobj (fastU8iArr) | N/A | 0.0012 | N/A | | | JSON | N/A | N/A | N/A | | | BSON | 2.1513 | 0.0013 | 10,485,776 | | | msgpack | 3.4741 | 1.4098 | 10,485,772 | | Large Uint8Array (100MB) | bobj | 18.8989 | 15.2495 | 104,857,612 | | | bobj (sync) | 17.8462 | 15.1305 | 104,857,612 | | | bobj (fastU8iArr) | N/A | 0.0012 | N/A | | | JSON | N/A | N/A | N/A | | | BSON | N/A | N/A | N/A | | | msgpack | 35.0774 | 15.1874 | 104,857,612 | | Deep Nested (depth=10, string at last level) | bobj | 1.2739 | 0.7761 | 6,972 | | | bobj (sync) | 0.9884 | 0.5930 | 6,972 | | | bobj (fastU8iArr) | N/A | 0.5478 | N/A | | | JSON | 0.3507 | 0.0460 | 6,015 | | | BSON | 0.2978 | 0.0663 | 8,020 | | | msgpack | 0.2612 | 0.2267 | 3,011 | | Deep Nested (depth=10, 10MB at last level) | bobj | 1.5191 | 1.6598 | 10,485,851 | | | bobj (sync) | 1.8928 | 1.5833 | 10,485,851 | | | bobj (fastU8iArr) | N/A | 0.0065 | N/A | | | JSON | N/A | N/A | N/A | | | BSON | 2.1945 | 0.0012 | 10,485,856 | | | msgpack | 3.3996 | 1.4840 | 10,485,802 | | Deep Nested (depth=1000, string at last level)| bobj | 1.0393 | 0.7277 | 6,972 | | | bobj (sync) | 0.9754 | 0.5520 | 6,972 | | | bobj (fastU8iArr) | N/A | 0.5602 | N/A | | | JSON | 0.3607 | 0.0470 | 6,015 | | | BSON | 0.2759 | 0.0417 | 8,020 | | | msgpack | 0.2568 | 0.1952 | 3,011 | | Deep Nested (depth=1000, 10MB at last level) | bobj | 3.3488 | 3.0316 | 10,493,771 | | | bobj (sync) | 3.2013 | 2.8082 | 10,493,771 | | | bobj (fastU8iArr) | N/A | 0.5609 | N/A | | | JSON | N/A | N/A | N/A | | | BSON | N/A | N/A | N/A | | | msgpack | 3.9857 | 1.7409 | 10,488,772 |

Notes:

  • "N/A" means the method is not applicable due to format limitations (e.g., JSON cannot handle Uint8Array, BSON has a 16MB document size limit).
  • All times are averages over 1000 runs, measured in milliseconds.
  • Data size is the serialized byte length.
  • The fast version of bobj deserialization uses import { fastU8iArrDeserializerPlugin } from "bobj", this will accelerate the parsing of Uint8Array type data; however, the parsed data will contain references to the original data.
  • For deep nested cases, only the deepest level contains the actual data (Uint8Array), while all upper levels are just nested objects without additional payload.
  • Implementations used in the benchmark:
    • JSON: Bun built-in JSON.stringify and JSON.parse
    • BSON: bson (BSON.serialize, BSON.deserialize)
    • msgpack: msgpack-lite (msgpack.encode, msgpack.decode)

bobj Binary Format Specification

Each element in the bobj binary follows this structure:

| 8 bits | 8 bits | 8 bits | Variable bits | Variable bits | Variable bits | Variable bits | |--------------|--------------|--------------|---------------|---------------|---------------|---------------| | Key length | Value type length | Value length length | Key | Value type | Value length | Value data |

  • Key length: Length of the key (in bytes, 0-255).
  • Value type length: Length of the value type identifier (e.g., "Number", "Date", in bytes, 0-255).
  • Value length length: Length of the value length field (in bytes, 0-255).
  • Key: UTF-8 encoded key string.
  • Value type: UTF-8 encoded type identifier (e.g., "String", "Array").
  • Value length: Binary representation of the value data length (converted via int2bytes).
  • Value data: Binary data of the value (e.g., string bytes, number bytes).

License

MIT © MiaoSpring