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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mpen/jsjson

v0.2.3

Published

Compact cross-platform JSON serialization supporting any JavaScript data type.

Readme

@mpen/jsjson

Compact, type-preserving, and high-performance JSON serialization for standard and rich JavaScript data types. Targets both Browser and Node (neutral).

Standard JSON.stringify silently strips rich data types (such as Date, Map, Set, BigInt, RegExp, URL, TypedArrays, and Symbol) or coerces them to simpler types (like converting -0, NaN, and Infinity to standard 0 or null).

@mpen/jsjson serializes any rich JavaScript datatype into an extremely compact, recursive array-prefixing format that preserves exact type integrity, and parses it back flawlessly.


Key Features

  • Compact Array-Prefixing Schema: Special data nodes (e.g. Dates, Maps, Sets, buffers, BigInts, etc.) are serialized into arrays prefixed by a compact integer type ID (e.g. [3,123456] for Date, [11,1,2,3] for ArrayBuffer). Primitive types and plain objects require zero overhead and serialize directly to standard JSON without wrapping.
  • Automatic Tabular Optimization (TABLE): Detects when an array contains plain objects with identical key sets, extracting the schema keys once and serializing rows into a value-only matrix. This avoids repeating key strings (like "id", "name") for large data payloads.
  • Broader Datatype Support: Out-of-the-box support for 19+ different datatypes, including global/local Symbols, ArrayBuffer, typed arrays (e.g., Uint8Array, Float64Array), DataView, URL, Error callstacks, and special numbers (like -0, NaN, and Infinity).
  • Clean, Explicit Security Boundaries: Standard native JSON behavior is maintained; circular structures throw a TypeError and functions throw a clear exception rather than silently converting to undefined or executing insecure code.
  • Zero Dependency Overhead: Fully neutral, lightweight footprint with strict TypeScript types.

Installation

bun add @mpen/jsjson

Usage

Preserving Rich Types

import { jsjStringify, jsjParse } from '@mpen/jsjson'

const original = {
    date: new Date(123456),
    set: new Set([1, 2, 3]),
    big: 12345678901234567890n,
    regex: /foo/gi,
    url: new URL('https://example.com'),
    nanValue: NaN,
    negativeZero: -0,
}

// 1. Stringify to compact JSON string
const json = jsjStringify(original)
console.log(json)
// Yields: {"date":[3,123456],"set":[2,1,2,3],"big":[6,"12345678901234567890"],...}

// 2. Parse back with full type safety
const parsed = jsjParse<typeof original>(json)

console.log(parsed.date instanceof Date) // true
console.log(parsed.set instanceof Set) // true
console.log(parsed.big === 12345678901234567890n) // true
console.log(Object.is(parsed.negativeZero, -0)) // true

Tabular Schema (TABLE) Optimization

If you stringify an array of objects that share identical key lists, @mpen/jsjson automatically optimizes the payload into a schema header and row values:

const users = [
    { name: 'Alice', age: 30 },
    { name: 'Bob', age: 25 },
]

const json = jsjStringify(users)
console.log(json)
// Yields: [4,["age","name"],[[30,"Alice"],[25,"Bob"]]]

Key strings ("name", "age") are printed only once in the header array, significantly shrinking large data collection payloads!


Supported Datatypes

Every value maps to a compact, single- or double-digit integer ID:

| Datatype | Enum Member | ID | Serialized Form Example | | :---------------------- | :-------------------------- | :--- | :------------------------------ | | undefined | JsType.UNDEFINED | 0 | [0] | | null | - | - | null | | string | - | - | "hello" | | number | - | - | 42 | | true | - | - | true | | false | - | - | false | | Array | JsType.ARRAY | 1 | [1,1,2,3] | | Object | - | - | {"a":1} | | Date | JsType.DATE | 3 | [3,123456] | | TABLE (Optimized) | JsType.TABLE | 4 | [4,["a"],[[1],[2]]] | | Map | JsType.MAP | 5 | [5,["k","v"]] | | Set | JsType.SET | 2 | [2,1,2] | | RegExp | JsType.REGEX | 7 | [7,"foo","gi"] | | BigInt | JsType.BIGINT | 6 | [6,"1234567890"] | | Symbol (with key) | JsType.SYMBOL_WITH_KEY | 10 | [10,"sym_key"] | | Symbol (without key) | JsType.SYMBOL_WITHOUT_KEY | 29 | [29,"sym_desc"] | | Error | JsType.ERROR | 9 | [9,"TypeError","msg","stack"] | | URL | JsType.URL | 8 | [8,"https://foo.com"] | | ArrayBuffer | JsType.ARRAY_BUFFER | 11 | [11,"AQID"] | | Uint8Array | JsType.UINT8_ARRAY | 13 | [13,"BAUG"] | | Node.js Buffer | JsType.NODE_BUFFER | 24 | [24,"BwgJ"] | | DataView | JsType.DATA_VIEW | 23 | [23,"CgQ="] | | NaN | JsType.NAN | 25 | [25] | | Infinity | JsType.INFINITY | 26 | [26] | | -Infinity | JsType.NEG_INFINITY | 27 | [27] | | -0 | JsType.NEG_ZERO | 28 | [28] |


Comparison: @mpen/jsjson vs superjson

While both libraries aim to solve type preservation across serialization boundaries, they make different architectural trade-offs:

1. Serialized Output Size (Compactness)

  • superjson: Generates a standard JSON object paired with a separate verbose, string-path-based metadata block mapping type tags to keys:
    // superjson output:
    {
        "json": { "date": "1970-01-01T00:02:03.456Z" },
        "meta": { "values": { "date": ["Date"] } }
    }
    Size: ~112 characters.
  • @mpen/jsjson: Encodes nodes as recursive prefix arrays or direct JSON primitives/objects:
    // jsjson output:
    { "date": [3, 123456] }
    Size: 21 characters (~81% smaller).

2. Tabular Schema Optimizations

  • superjson: Does not optimize arrays of objects. Key strings are repeated on every element inside the JSON tree, bloating payloads for database results or large client lists.
  • @mpen/jsjson: Automatically packages lists of matching-key objects into high-performance, single-instance schema headers (JsType.TABLE), dropping key-string duplication altogether.

3. Out-of-the-Box Type Support

Our package supports a wider array of standard and rich JS primitives:

  • @mpen/jsjson: Native out-of-the-box support for ArrayBuffer, all typed arrays (e.g., Uint8Array, Float64Array), DataView, URL, global/local Symbols, and strict preservation of -0, NaN, Infinity, and -Infinity using lightweight 4-character representations.
  • superjson: Lacks out-of-the-box support for typed arrays, ArrayBuffer, global/local Symbols, and -0 sign preservation unless custom registers are manually injected.

4. CPU & Memory Performance

  • superjson: Tracks nested string paths throughout standard objects recursively to assemble its complex meta tree, incurring higher CPU cycle and memory allocation overhead.
  • @mpen/jsjson: Traverses the tree in a single pass to build a standard JS array representation, and hands it off directly to standard native C++ JSON.stringify / JSON.parse. It is extremely fast and lightweight.

5. Circular References & Referential Equality (Trade-Off)

  • superjson: Supports reconstructing identical object references across the tree (referential equality) and serializes circular references by logging reference paths inside the meta block.
  • @mpen/jsjson: Focuses purely on data value serialization. It detects circular references and throws a clean TypeError (matching native JSON behavior), choosing not to reconstruct referential equality (recreated values are deep clones).

License

MIT