Skip to content

⚡️ Fast, compressed binary serializers in Node.js and HTML5

License

Notifications You must be signed in to change notification settings

reececomo/tinybuf

Repository files navigation

🔌 tinybuf  NPM version Minzipped Downloads Tests License

tinybuf icon showing binary peeking out from behind a square.

⚡Fast, compressed binary serializers in Node.js and HTML5

🔮 Simple, declarative API 🔥 Blazing fast serialization
🗜️ Powerful compression 💾 ^50% smaller than FlatBuffers
🍃 Zero dependencies 🙉 Strong, inferred types
🌐 Node / browser 🛡️ Built-in validation/transforms
🤏 ~4.4kb minzipped ✅ Property mangling (Terser)

💿 Install

npm install tinybuf

🕹 Example

import { defineFormat, Type } from 'tinybuf';

export const GameWorldData = defineFormat({
  frameNo: Type.UInt,
  timeRemaining: Type.Float16,
  players: [
    {
      id: Type.UInt,
      position: {
        x: Type.Float32,
        y: Type.Float32
      },
      joystick: {
        x: Type.Scalar8,
        y: Type.Scalar8
      },
      actions: Type.Bools // [ jump, attack ]
    }
  ]
});

Encode

Formats can be encoded directly:

let bytes = GameWorldData.encode({
  frameNo: 50,
  timeRemaining: 59.334,
  players: [
    {
      id: 1,
      position: { x: 123.5, y: 456.75 },
      joystick: { x: 0.75, y: -0.662 },
      actions: [ /* jump: */ true,
               /* attack: */ false ]
    }
  ]
});

bytes.byteLength
// 16

Or directly from objects:

let bytes = GameWorldData.encode( obj );

bytes.byteLength
// 16

Decode

Formats can be read in a number of ways:

  1. Simple – decode to object
  2. In-place – decode into an existing object
  3. Parser – register / decode many formats

Simple

Decode as a strongly-typed object.

let obj = GameWorldData.decode( bytes );
// { frameNo: number; timeRemaining: number; … }

In-place

Use for memory effiency - extract fields directly into an existing object instance. This prevents allocating new memory.

let obj: Decoded<typeof GameWorldData> = {} as any;

GameWorldData.decode( bytes, obj );

Parser – Decoding registered formats

  • Register formats with .on(format, handler, options?)
  • Trigger format handlers with .processBuffer(bytes)
import { bufferParser } from 'tinybuf';

// register
const parser = bufferParser()
  .on(MyChatMessage, msg => myHud.showChat(msg))
  .on(GameWorldData, data => myWorld.update(data), {
    decodeInPlace: true, // `data` gets recycled
  });

// parse
parser.processBuffer( bytes );

📘 Documentation

🏁 Quick start: Quick start guide,
Types
📑 Advanced: Async safety mode,
Format header collisions,
Compression tips,
Validation/transforms

Credits

tinybuf is based on Guilherme Souza's js-binary