Record IDs, nanosecond datetimes, decimals, and durations do not survive a round trip through plain JSON or untagged CBOR unchanged. SQON (SurrealQL Object Notation) is the wire format SurrealDB uses for these types. The @surrealdb/sqon package ships the codecs that convert between JavaScript value instances and that format.
When you use the surrealdb SDK over WebSocket or HTTP, those codecs run automatically on every request and response. You can also import them on their own if you are building a custom client, middleware, or data pipeline and do not need the full driver.
Available codecs
Two codecs are fully implemented today:
| Codec | Wire format | When to use |
|---|---|---|
CborCodec | Uint8Array (CBOR with SurrealDB tags) | RPC transport to SurrealDB - WebSocket and HTTP engines encode every request and decode every response with CBOR |
JsonCodec | Plain object tree (SQON JSON) | JSON-safe interchange - logging, caching, REST APIs, or any environment where binary CBOR is impractical |
Both codecs represent the same values. If you encode with one and decode with the other, types are preserved as long as you decode back into the matching value classes.
Note
Why you need a codec
Without one, SurrealDB-specific types get flattened or misread on the way in or out:
A
RecordIdcan turn into a plain string and lose its tableA
Decimalcan be rounded by JavaScript'snumbertypenonecan be confused with a missing JSON field or withnullDatetimes can drop from nanoseconds to milliseconds
That is why query results come back as DateTime, RecordId, and the other value classes: the CBOR codec decodes every inbound RPC message before your code sees it.
Using codecs with the SDK
A new Surreal instance registers default codecs. WebSocket and HTTP engines use CborCodec for RPC traffic, so you normally never call a codec yourself.
Pass codecOptions in the driver options to change decoding behaviour:
With useNativeDates set, datetimes decode as native Date objects instead of DateTime. You lose nanosecond precision, which is the trade-off if the rest of your code expects Date.
You can replace the default codec factories when you need custom encode or decode logic:
Using codecs standalone
Install @surrealdb/sqon when you only need serialisation and not the database client:
CBOR codec
CborCodec outputs compact binary. Reach for it when you speak SurrealDB's RPC protocol or want a small, type-safe binary payload.
The CBOR layout uses SurrealDB's tagged values. See the CBOR protocol reference for the tag list.
JSON codec
JsonCodec builds a JSON-safe object tree in SQON JSON notation. Typed values sit inside wrapper objects such as $recordId, $datetime, and $decimal:
Decode the structure back to value instances:
JsonCodec fits logging, browser storage, and anything that only accepts JSON/text such as LLMs. CborCodec fits talking to SurrealDB directly and cases where size and binary safety matter.
Choosing a codec
| Scenario | Recommended codec |
|---|---|
| WebSocket or HTTP RPC to SurrealDB | CborCodec (used automatically by the SDK) |
| Storing query results in a JSON document store | JsonCodec or jsonify() for string representations |
| Logging or debugging typed values | JsonCodec or jsonify() |
| Custom RPC client implementation | CborCodec |
Browser storage (localStorage, IndexedDB as JSON) | JsonCodec |
For a plain string form (good for display or simple serialisation), jsonify() converts value instances to SurrealQL strings without the SQON JSON wrappers.
Codec options
Both codecs accept a shared CodecOptions object:
| Option | Description |
|---|---|
useNativeDates | Decode datetimes as native Date instead of DateTime (loses nanosecond precision) |
valueEncodeVisitor | Custom function applied to each value before encoding |
valueDecodeVisitor | Custom function applied to each value after decoding |
Use valueEncodeVisitor and valueDecodeVisitor to map values to your own types, or to strip fields before encoding.
Learn more
CBOR protocol reference for the full CBOR tag specification
Value types for the value classes codecs operate on
Utilities for
jsonify()and other SQON helpers@surrealdb/sqonon npm for standalone installation