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

structon

v1.0.7

Published

Random-access struct encoding/decoding as an extensible class for msgpackr, cbor-x, and compatible encoders

Downloads

8,044

Readme

structon

Random-access struct encoding/decoding as an extensible class for msgpackr, cbor-x, and compatible binary encoders.

Overview

structon extracts the random-access struct functionality from msgpackr's struct.js into a standalone, class-based package. It exposes a createStructon(BaseClass) factory that returns a class extending any compatible encoder. The resulting class encodes top-level plain objects as compact fixed-width structs with lazy-access property getters, while delegating inner nested-object encoding to the underlying base encoder (msgpackr or cbor-x).

Binary format compatibility: the byte layout produced by structon is identical to msgpackr's struct.js format. Data written by either implementation can be read by the other.

Key features

  • Zero-copy lazy access — property getters read directly from the raw buffer; no full deserialization needed to access a single field.
  • Extensible base class — extend msgpackr's Packr/Encoder or cbor-x's Encoder (or any compatible encoder).
  • Structure caching — structure definitions are incrementally learned and can be persisted via saveStructures/getStructures callbacks.
  • Nested struct support — nested plain objects are encoded by the base encoder; nested structs within a struct field are handled recursively.
  • Binary compatible with msgpackr's struct.js random-access format.

Installation

npm install structon
# peer dependency for msgpackr usage:
npm install msgpackr
# or for cbor-x:
npm install cbor-x

Usage

With msgpackr

import { Packr } from 'msgpackr';
import { createStructon } from 'structon';

const Structon = createStructon(Packr);

// Persist structures so they survive process restarts
let savedStructures = null;
const enc = new Structon({
    structures: [],
    saveStructures(s) { savedStructures = s; },
    getStructures()   { return savedStructures; },
});

const buf = enc.encode({ name: 'Alice', age: 30, score: 99.5 });
const obj = enc.decode(buf);

console.log(obj.name);  // 'Alice'  — reads from buffer without full decode
console.log(obj.age);   // 30
console.log(obj.toJSON());  // { name: 'Alice', age: 30, score: 99.5 }

With cbor-x

import { Encoder } from 'cbor-x';
import { createStructon } from 'structon';

const Structon = createStructon(Encoder);
const enc = new Structon({ structures: [] });

const buf = enc.encode({ id: 1, label: 'widget' });
const obj = enc.decode(buf);
console.log(obj.id);     // 1
console.log(obj.label);  // 'widget'

Non-struct values pass through

Values that are not plain objects (arrays, strings, numbers, Maps, etc.) are encoded and decoded by the base class transparently.

enc.encode([1, 2, 3]);          // regular msgpack/cbor array
enc.encode('hello');             // regular msgpack/cbor string
enc.encode(new Map([['a', 1]])); // regular msgpack/cbor map

API

createStructon(BaseClass)

Returns a Structon class that extends BaseClass.

Parameters

  • BaseClassPackr from msgpackr, Encoder from cbor-x, or any compatible encoder class.

Returns a class with the following additions over BaseClass:

| Member | Description | |--------|-------------| | encode(value) | Encodes plain objects as structs; other values via base class. | | decode(buffer) | Decodes struct buffers into lazy objects; other buffers via base class. | | typedStructs | Array of learned structure definitions (auto-populated). | | _decodeSliceDirect(src, start, end) | Low-level slice decoder used by struct getters. |

Constructor options

All options from the base class are forwarded. Additional behaviour:

| Option | Description | |--------|-------------| | structures | Shared structure definitions array (passed to base class). | | saveStructures(s) | Called when new struct definitions are learned (msgpackr API). | | getStructures() | Called to load previously saved structures (msgpackr API). | | saveShared(s) | cbor-x equivalent of saveStructures. | | getShared() | cbor-x equivalent of getStructures. |

Binary format

The format is identical to msgpackr's struct.js:

[header (1-4 bytes)][fixed-width field section][variable ref section]
  • Header: record ID encoded as 0x20 + id (single byte for ids 0-15), or 0x38/0x39/0x3a with 1/2/3 extra bytes for larger IDs.
  • Fixed section: one fixed-width slot per field — numbers as uint8/uint32/float64, strings as 0/1/2-byte ref offsets, objects as 2/4-byte ref offsets, dates as float64.
  • Ref section: UTF-8 string bytes followed by msgpack/cbor-encoded object bytes.

Field access resolves directly from the buffer — only the bytes for the accessed field are read.

Interoperability with msgpackr

structon is bidirectionally byte-compatible with msgpackr's randomAccessStructure: true mode (msgpackr ≤ 1.11.10, before its struct.js was removed). The test suite verifies all four directions:

  • Structon writes → native Packr reads
  • native Packr writes → Structon reads
  • byte-identical output for a given plain object
  • mixed types + nested objects round-trip when structures and typedStructs are shared

These compatibility tests pin msgpackr 1.11.10 as a dev dependency.

License

Apache 2.0 — see LICENSE.