Ext-JSON
Ext-JSON is the standard JSON serialization layer for Primebrick backend
services. It uses json-bigint with useNativeBigInt: true to preserve
bigint values across the JSON wire format.
Why Ext-JSON exists
Standard JSON.stringify() throws on bigint:
Code
Primebrick uses native bigint for all integer IDs (UUIDs are strings, but
numeric IDs, timestamps, and counters are bigint). Ext-JSON makes the types
predictable across the wire format:
| JSON value | Wire format | Parsed TS type |
|---|---|---|
42n (bigint) | 42 | bigint |
42 (small int) | 42 | bigint (reviver forces it) |
3.14 (float) | 3.14 | number |
1e5 (scientific) | 100000 | bigint (integer) |
"alice" (string) | "alice" | string |
true (boolean) | true | boolean |
null | null | null |
The rule is simple: every integer is bigint, every float is number.
No number | bigint ambiguity — the type is determined by whether the value
has a decimal point, not by its magnitude.
The reviver
extJsonParse uses a reviver that forces every integer to bigint:
Code
json-bigint's alwaysParseAsBig option would do this, but it is broken for
floats in v1.0.0 — so the SDK uses a reviver instead. The reviver is the
reason 42 (a small integer that json-bigint returns as number) becomes
bigint on the receiving end, matching the 42n the sender wrote.
Usage
Direct functions
Code
Round-trip type preservation
The round-trip preserves types exactly — bigint in, bigint out; number
in, number out. This is what makes the SDK's NATS™ and HTTP layers safe for
DAL rows that mix bigint IDs with number floats:
Code
The one asymmetry to know about: a plain number integer on the sender
becomes bigint on the receiver. This is intentional — it makes every
integer bigint everywhere, so consumers never write number | bigint union
types. If you send a number integer, expect a bigint back.
Express middleware (BE)
Code
The middleware replaces res.json() with Ext-JSON serialization. The body
parser replaces express.json() with BigInt-safe parsing so that large
integer values in request bodies (e.g. bigint config values) are parsed
as native bigint instead of losing precision through JSON.parse. Install
both once before any routes.
NATS™ (microservices)
NatsClient.publish(), subscribe(), and subscribeRequest() use Ext-JSON
internally. Microservice code never calls extJsonStringify / extJsonParse
directly — just pass plain objects and receive plain objects.
Sub-path import
If you need only the JSON functions without pulling in NATS™/auth code paths:
Code
Not for the frontend
The frontend has its own standalone wrapper (src/lib/api-ext.ts) that installs
json-bigint directly. The FE does not depend on @primebrick/sdk. Ext-JSON
is for BE and microservices only.
Next steps
- NATS Client — uses Ext-JSON internally
- HTTP Server — uses Ext-JSON for health and error responses
- API Reference — extJsonStringify, extJsonParse, extJsonMiddleware, extJsonBodyParser