Skip to content

IdiotStudios/JS-BinaryWire

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

23 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

BiWi - Binary Wire Protocol

A streaming, binary-first alternative to JSON designed for low-latency, incremental data transmission. BiWi encodes messages in raw binary, allowing clients to send fields and chunks as they arrive, and servers to start processing instantly.

Features

๐ŸŒˆ AI Git Commit Comments - Thanks for that github, saved me time.

โœจ Binary-First Design - Compact, efficient binary encoding

๐Ÿš€ Low-Latency - Minimal overhead, optimized for real-time communication

๐Ÿ“ก Streaming Support - Send data in chunks for incremental processing

๐ŸŽฎ Game Networking - Perfect for multiplayer games and real-time apps

๐Ÿ”’ Type System - Full support for typed fields (int32, int64, float32, float64, strings, binary, arrays, objects)

โšก Real-Time - Process messages as they arrive without waiting for completion

๐Ÿงฉ Modular - Clean separation between core, server, and client modules

Benchmarks

Command: npm run test:benchmark

  • BiWi: ~84k msgs/sec (1000 msgs, 200-msg warm-up)
  • JSON (NDJSON): ~124k msgs/sec (1000 msgs, 200-msg warm-up)
  • Protobuf (len-prefix): ~125k msgs/sec (1000 msgs, 200-msg warm-up)

Notes:

  • Throughput tests include an 8s safety timeout to prevent hangs.
  • Warm-up requests stabilize JIT/GC before timing.

Installation

Its not on npm so wont work lol

npm install binarywire 

Quick Start

Server

import { BiWiServer, BiWiMessage } from 'binarywire/server';

const server = new BiWiServer({ port: 3000 });

// Handle incoming messages
server.on(1, (connection, value) => {
  console.log('Received:', value);
  
  // Send response
  const response = new BiWiMessage();
  response.setField(2, 'Got it!');
  connection.send(response);
});

server.listen();

Client

import { BiWiClient, BiWiMessage } from 'binarywire/client';

const client = new BiWiClient({ host: 'localhost', port: 3000 });

await client.connect();

// Send message
const msg = new BiWiMessage();
msg.setField(1, 'Hello Server!');
await client.send(msg);

// Handle responses
client.on('field', ({ fieldId, value }) => {
  console.log(`Field ${fieldId}:`, value);
});

Protocol Overview

Message Format

Each BiWi message consists of one or more fields:

[Field 1][Field 2][Field 3]...
  โ”‚       โ”‚       โ”‚
  โ”œโ”€โ†’ [fieldId: 2 bytes][fieldType: 1 byte][value]
  โ”œโ”€โ†’ [fieldId: 2 bytes][fieldType: 1 byte][value]
  โ””โ”€โ†’ [fieldId: 2 bytes][fieldType: 1 byte][value]

Supported Types

  • NULL (0x00) - Null value
  • BOOLEAN (0x01) - True/False
  • INT32 (0x02) - 32-bit integer
  • INT64 (0x03) - 64-bit integer
  • FLOAT32 (0x04) - Single-precision float
  • FLOAT64 (0x05) - Double-precision float
  • STRING (0x06) - UTF-8 string
  • BINARY (0x07) - Raw binary data
  • ARRAY (0x08) - Ordered collection
  • OBJECT (0x09) - Key-value mapping
  • CHUNK_START (0x0A) - Begin streaming chunk
  • CHUNK_DATA (0x0B) - Chunk payload
  • CHUNK_END (0x0C) - End streaming

Streaming Example

Send large data in chunks without waiting for completion:

const encoder = new BiWiEncoder();
encoder.encodeChunkStart(1, totalSize);
encoder.encodeChunkData(0, chunk1);
encoder.encodeChunkData(1, chunk2);
encoder.encodeChunkEnd();

const buffer = encoder.toBuffer();

Core Modules

binarywire/core

Low-level encoding/decoding:

import { BiWiEncoder, BiWiDecoder, BiWiTypes } from 'binarywire/core';

// Encode
const encoder = new BiWiEncoder();
encoder.encodeField(1, 'Hello');
encoder.encodeField(2, 42);
const buffer = encoder.toBuffer();

// Decode
const decoder = new BiWiDecoder(buffer);
const fields = decoder.decodeAll();

binarywire/server

Server implementation:

import { BiWiServer } from 'binarywire/server';

const server = new BiWiServer({ port: 3000 });
server.listen();

binarywire/client

Client implementation:

import { BiWiClient } from 'binarywire/client';

const client = new BiWiClient({ host: 'localhost', port: 3000 });
await client.connect();

Examples

Run the example server:

npm run example:server

Run the example client (in another terminal):

npm run example:client

Use Cases

  • Game Networking - Low-latency, efficient multiplayer communication
  • Real-Time Applications - Live dashboards, monitoring systems
  • IoT Devices - Minimal bandwidth overhead
  • Microservices - Fast inter-service communication
  • Streaming Data - Incremental data transmission
  • Live Updates - Push updates with minimal latency

Performance Characteristics

  • Fixed-size types: 5-9 bytes per field (type + value)
  • Variable-size types: 3 bytes overhead + payload
  • Field headers: 3 bytes (2 bytes field ID + 1 byte type)
  • No framing overhead - Pack multiple fields into a single message

API Reference

BiWiMessage

const msg = new BiWiMessage();
msg.setField(fieldId, value);
msg.getField(fieldId);
msg.toBuffer();
msg.getSize();

BiWiServer

const server = new BiWiServer(options);
server.listen();
server.on(fieldId, handler);
server.broadcast(message);
server.sendToClient(connectionId, message);
server.close();

BiWiClient

const client = new BiWiClient(options);
await client.connect();
client.send(message);
client.onField(fieldId, handler);
client.disconnect();

License

Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)

Contributing

Contributions are welcome! Please feel free to submit pull requests. Probably wont see it but heck do it anyway.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Contributors