⚡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) |
npm install tinybuf
import { defineFormat, Type } from 'tinybuf';
export const GameWorldState = 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]
}
]
});
Formats can then be encoded:
let bytes: Uint8Array = GameWorldState.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: Uint8Array = GameWorldState.encode( world );
bytes.byteLength
// 16
Decode as a strongly-typed object.
let obj = GameWorldData.decode( bytes );
// { frameNo: number; timeRemaining: number; … }
Extract fields directly into an existing object (this minimizes memory footprint).
let obj: Decoded<typeof GameWorldData> = {} as any;
GameWorldData.decodeInPlace( bytes, obj );
- 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 );
Type | JavaScript Type | Bytes | Notes |
---|---|---|---|
Int |
number |
1-4* | A signed integer from -Number.MAX_SAFE_INTEGER to Number.MAX_SAFE_INTEGER . |
Int8 |
number |
1 | A signed integer from -128 to 127. |
Int16 |
number |
2 | A signed integer from -32,768 to 32,767. |
Int32 |
number |
4 | A signed integer from -2,147,483,648 to 2,147,483,647. |
UInt |
number |
1-4# | An unsigned integer from 0 to Number.MAX_SAFE_INTEGER . |
UInt8 |
number |
1 | An unsigned integerfrom 0 to 255. |
UInt16 |
number |
2 | An unsigned integer from 0 to 65,535. |
UInt32 |
number |
4 | An unsigned integer from 0 to 4,294,967,295. |
Float64 |
number |
8 | A 64-bit double-precision floating-point number. |
Float32 |
number |
4 | A 32-bit single-precision floating-point number. |
Float16 |
number |
2 | A 16-bit half-precision floating-point number. Note: Low precision. Maximum effective range ±65,504. |
BFloat16 |
number |
2 | A bfloat16 format 16-bit half-precision floating-point number. Note: Lowest precision. Same effective range as Float32 . |
Scalar |
number |
1 | A signed scalar between -1.00 and 1.00 (two decimal precision). |
UScalar |
number |
1 | A scalar between 0.00 and 1.00 (two decimal precision). |
Bool |
boolean |
1 | A boolean value. |
Bools |
boolean[] |
1¶ | An array/tuple of boolean values (1 - 28) encoded as a single byte. |
Buffer |
Uint8Array |
1† + n | An ArrayBuffer or ArrayBufferLike . |
String |
string |
1† + n | A string (UTF-8 encoded). |
JSON |
any |
1† + n | Any JSON encodable value (encoded as a string). |
RegExp |
RegExp |
2† + n | JavaScript RegExp object. |
Date |
Date |
8 | JavaScript Date object. |
🏁 Quick start: | Quick start guide, Types |
📑 Advanced: | Async safety mode, Format header collisions, Compression tips, Validation/transforms |
tinybuf is based on Guilherme Souza's js-binary