Skip to content

CBOR serializer

CborSerializer encodes values using CBOR (RFC 8949) — a compact binary serialization format. More compact than JSON, faster for binary-heavy data, similar API surface.

import { CborSerializer } from 'actor-ts';
const serializer = new CborSerializer();
const bytes = serializer.toBinary({ kind: 'inc', n: 1 });
// → Uint8Array (binary CBOR, smaller than JSON)
const decoded = serializer.fromBinary(bytes, '');
// → { kind: 'inc', n: 1 }
You should switch to CBOR if…
Messages carry binary data (images, encoded payloads).
Cluster bandwidth is measurable / metered (cross-region, cellular IoT).
Persistence storage costs scale with payload size.
Sustained millions of small messages where JSON parse cost shows in profiles.

For most apps, JSON is fine — CBOR’s gains don’t justify the loss of human-debuggability.

PayloadJSONCBORSavings
{ kind: 'inc' }14 bytes9 bytes36 %
Order with 5 items250 bytes180 bytes28 %
Image bytes (10 KB)13.3 KB (base64)10 KB (native)25 %
Deeply nested objectvariesvariestypically 20-40 %

Bigger savings on binary data (no base64 overhead) and repeated field names (CBOR can string-table at the protocol level).

TypeJSONCBOR
Uint8Arraybase64 stringNative bytes
MapLost (becomes {})Native map
BigIntThrowsSupported via tag
DateISO stringNative via tag (epoch)
Float precision15-17 significant digitsFull IEEE 754

For data with binary fields or Map / BigInt, CBOR preserves the type info.

import { SerializationExtensionId, CborSerializer } from 'actor-ts';
const ext = system.extension(SerializationExtensionId);
ext.setDefault(new CborSerializer());

Now every cross-node tell, every persisted event, every durable-state write uses CBOR by default.

Per-class binding still works:

ext.bind(MyEvent, new ProtobufSerializer<MyEvent>());
// MyEvent uses Protobuf; everything else uses CBOR
import { CborSerializer } from 'actor-ts';
const ser = new CborSerializer();
const bytes = ser.toBinary({ data: someUint8Array });
// Later:
const back = ser.fromBinary(bytes, '') as { data: Uint8Array };

Useful when you want CBOR for a specific use case (e.g., HTTP response bodies for binary data) without switching the cluster default.

CBOR is a binary tagged format. Inspecting raw bytes requires a CBOR-aware tool:

Terminal window
$ cat events.cbor | cbor-diag
# decoded to diagnostic notation

For debugging, you may want to briefly switch to JSON when hunting a bug, then switch back.

The framework’s CBOR implementation is internal — pure JS, no extra dependencies. Compliant with RFC 8949.

For external interop (sending CBOR to non-actor-ts systems), the framework’s encoding follows the standard — any RFC-8949-compliant decoder reads it.