PrimeBrickPrimeBrick
  • Docs
  • Contact
  • MIT License
  • Documentation
  • MCP Server
  • API Catalog
  • Services
  • Libraries
PrimeBrickPrimeBrick

© 2026 PrimeBrick. MIT License. v3.8.0

github
DAL Library
SDK Library
    OverviewGetting StartedAuthenticationExt-JSONRedis cache layerConfig tables & ConfigLoaderNATS™ ClientService RegistrationHTTP ServerSSE StandardPresenceAPI Reference
powered by Zudoku
SDK Library

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
JSON.stringify({ id: 42n }); // TypeError: Do not know how to serialize a BigInt

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 valueWire formatParsed TS type
42n (bigint)42bigint
42 (small int)42bigint (reviver forces it)
3.14 (float)3.14number
1e5 (scientific)100000bigint (integer)
"alice" (string)"alice"string
true (boolean)trueboolean
nullnullnull

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
extJsonParse(text, (_key, value) => { if (typeof value === "number" && Number.isInteger(value)) { return BigInt(value); } return value; });

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
import { extJsonStringify, extJsonParse } from "@primebrick/sdk"; const data = { entity_id: 42n, price: 3.14, name: "widget" }; const json = extJsonStringify(data); // → '{"entity_id":42,"price":3.14,"name":"widget"}' const parsed = extJsonParse<{ entity_id: bigint; price: number; name: string }>(json); // parsed.entity_id → 42n (bigint) // parsed.price → 3.14 (number)

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
const original = { id: 42n, // bigint → bigint count: 7, // number (integer) → bigint (reviver forces it) price: 3.14, // number (float) → number name: "widget", // string → string active: true, // boolean → boolean nested: { qty: 100n },// bigint nested → bigint }; const roundTrip = extJsonParse<typeof original>(extJsonStringify(original)); // typeof roundTrip.id → "bigint" // typeof roundTrip.count → "bigint" (was a number, now bigint — by design) // typeof roundTrip.price → "number" // typeof roundTrip.name → "string" // typeof roundTrip.nested.qty → "bigint"

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
import { extJsonMiddleware } from "@primebrick/sdk"; app.use(extJsonMiddleware()); // res.json() now uses Ext-JSON serialization for all subsequent responses

The middleware replaces res.json() with Ext-JSON serialization. Install it 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
import { extJsonStringify, extJsonParse, extJsonMiddleware } from "@primebrick/sdk/json";

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
Last modified on July 26, 2026
AuthenticationRedis cache layer
On this page
  • Why Ext-JSON exists
  • The reviver
  • Usage
    • Direct functions
    • Round-trip type preservation
    • Express middleware (BE)
    • NATS™ (microservices)
  • Sub-path import
  • Not for the frontend
  • Next steps
TypeScript
TypeScript
TypeScript
TypeScript
TypeScript
TypeScript