Extended JSON functionality for converting BSON data to/from human-readable JSON format while preserving type information and ensuring round-trip fidelity.
Parse Extended JSON string to JavaScript/BSON objects with type preservation.
/**
* Parse Extended JSON string to JavaScript/BSON objects
* @param text - Extended JSON string to parse
* @param options - Optional parsing configuration
* @returns Parsed JavaScript object with BSON types
*/
function parse(text: string, options?: EJSONOptions): any;
interface EJSONOptions {
/** Output using Extended JSON v1 spec (default: false) */
legacy?: boolean;
/** Return native JS types when possible rather than BSON types (default: true) */
relaxed?: boolean;
/** Use native BigInt for 64-bit integers (default: false) */
useBigInt64?: boolean;
}Usage Examples:
import { EJSON } from "bson";
// Parse with BSON types preserved
const ejsonString = '{ "id": { "$oid": "507f1f77bcf86cd799439011" }, "count": { "$numberLong": "42" } }';
const strict = EJSON.parse(ejsonString, { relaxed: false });
console.log(strict.id); // ObjectId instance
console.log(strict.count); // Long instance
// Parse with relaxed mode (native JS types when possible)
const relaxed = EJSON.parse(ejsonString, { relaxed: true });
console.log(relaxed.id); // ObjectId instance (can't convert to string)
console.log(relaxed.count); // 42 (converted to number)
// Parse with BigInt support
const bigIntString = '{ "bigValue": { "$numberLong": "9223372036854775807" } }';
const withBigInt = EJSON.parse(bigIntString, { useBigInt64: true });
console.log(typeof withBigInt.bigValue); // "bigint"Convert JavaScript/BSON objects to Extended JSON string format.
/**
* Convert JavaScript/BSON objects to Extended JSON string
* @param value - Object to convert to Extended JSON
* @param replacer - Function or array to transform values (like JSON.stringify)
* @param space - Indentation for pretty-printing (like JSON.stringify)
* @param options - Optional stringification configuration
* @returns Extended JSON string representation
*/
function stringify(
value: any,
replacer?: Function | Array,
space?: string | number,
options?: EJSONOptions
): string;Usage Examples:
import { EJSON, ObjectId, Long } from "bson";
const document = {
_id: new ObjectId(),
count: Long.fromNumber(42),
timestamp: new Date(),
binary: new Uint8Array([1, 2, 3, 4])
};
// Strict Extended JSON with type preservation
const strict = EJSON.stringify(document, undefined, 2, { relaxed: false });
console.log(strict);
// {
// "_id": { "$oid": "..." },
// "count": { "$numberLong": "42" },
// "timestamp": { "$date": "2023-..." },
// "binary": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
// }
// Relaxed Extended JSON (more readable)
const relaxed = EJSON.stringify(document, undefined, 2, { relaxed: true });
console.log(relaxed);
// {
// "_id": { "$oid": "..." },
// "count": 42,
// "timestamp": "2023-...",
// "binary": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
// }
// With custom replacer function
const filtered = EJSON.stringify(document, (key, value) => {
if (key === 'binary') return undefined; // Exclude binary data
return value;
});Serialize BSON objects to Extended JSON object representation (not string).
/**
* Serialize BSON objects to Extended JSON object representation
* @param bson - BSON object to serialize
* @param options - Optional serialization configuration
* @returns Extended JSON object (not string)
*/
function serialize(bson: any, options?: EJSONOptions): any;Usage Examples:
import { EJSON, ObjectId, Decimal128 } from "bson";
const bsonDoc = {
_id: new ObjectId(),
price: Decimal128.fromString("19.99"),
active: true
};
// Serialize to Extended JSON object
const ejsonObj = EJSON.serialize(bsonDoc, { relaxed: false });
console.log(ejsonObj);
// {
// _id: { $oid: "..." },
// price: { $numberDecimal: "19.99" },
// active: true
// }
// Can be used with regular JSON.stringify for final string conversion
const jsonString = JSON.stringify(ejsonObj, null, 2);Deserialize Extended JSON object back to JavaScript/BSON objects.
/**
* Deserialize Extended JSON object to JavaScript/BSON objects
* @param ejson - Extended JSON object to deserialize
* @param options - Optional deserialization configuration
* @returns JavaScript object with BSON types
*/
function deserialize(ejson: any, options?: EJSONOptions): any;Usage Examples:
import { EJSON } from "bson";
// Extended JSON object (not string)
const ejsonObj = {
_id: { $oid: "507f1f77bcf86cd799439011" },
count: { $numberLong: "42" },
price: { $numberDecimal: "19.99" },
timestamp: { $date: "2023-10-15T10:30:00.000Z" }
};
// Deserialize to BSON objects
const bsonDoc = EJSON.deserialize(ejsonObj, { relaxed: false });
console.log(bsonDoc._id); // ObjectId instance
console.log(bsonDoc.count); // Long instance
console.log(bsonDoc.price); // Decimal128 instance
console.log(bsonDoc.timestamp); // Date instance
// Deserialize with relaxed mode
const relaxedDoc = EJSON.deserialize(ejsonObj, { relaxed: true });
console.log(typeof relaxedDoc.count); // "number" (if within safe range)Extended JSON provides a way to represent BSON types in JSON format. There are two modes:
All BSON types are explicitly marked with $type indicators:
{
"_id": { "$oid": "507f1f77bcf86cd799439011" },
"count": { "$numberLong": "42" },
"price": { "$numberDecimal": "19.99" },
"timestamp": { "$date": "2023-10-15T10:30:00.000Z" },
"binary": { "$binary": { "base64": "AQIDBA==", "subType": "00" } },
"regex": { "$regularExpression": { "pattern": "^test", "options": "i" } }
}Native JSON types are used when possible for better readability:
{
"_id": { "$oid": "507f1f77bcf86cd799439011" },
"count": 42,
"price": { "$numberDecimal": "19.99" },
"timestamp": "2023-10-15T10:30:00.000Z",
"binary": { "$binary": { "base64": "AQIDBA==", "subType": "00" } },
"regex": "/^test/i"
}// ObjectId
new ObjectId() → { "$oid": "507f1f77bcf86cd799439011" }
// Long (strict mode)
Long.fromNumber(42) → { "$numberLong": "42" }
// Long (relaxed mode, when safe)
Long.fromNumber(42) → 42
// Decimal128
Decimal128.fromString("19.99") → { "$numberDecimal": "19.99" }
// Binary
new Binary([1,2,3,4]) → { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
// Date (strict mode)
new Date() → { "$date": "2023-10-15T10:30:00.000Z" }
// Date (relaxed mode)
new Date() → "2023-10-15T10:30:00.000Z"
// RegExp (strict mode)
/pattern/flags → { "$regularExpression": { "pattern": "pattern", "options": "flags" } }
// RegExp (relaxed mode)
/pattern/flags → "/pattern/flags"
// Timestamp
new Timestamp(1, 1697365800) → { "$timestamp": { "t": 1697365800, "i": 1 } }
// MinKey/MaxKey
new MinKey() → { "$minKey": 1 }
new MaxKey() → { "$maxKey": 1 }Extended JSON ensures perfect round-trip conversion:
import { EJSON, serialize, deserialize } from "bson";
const original = {
_id: new ObjectId(),
bigNumber: Long.fromString("9223372036854775807"),
precise: Decimal128.fromString("123.456789012345678901234567890")
};
// BSON → Extended JSON → BSON
const ejsonString = EJSON.stringify(original, undefined, undefined, { relaxed: false });
const restored = EJSON.parse(ejsonString, { relaxed: false });
// Should be identical to original
console.log(original._id.equals(restored._id)); // true
console.log(original.bigNumber.equals(restored.bigNumber)); // true
console.log(original.precise.toString() === restored.precise.toString()); // true
// Also works with binary serialization
const bsonBytes = serialize(original);
const fromBson = deserialize(bsonBytes);
const ejsonFromBson = EJSON.stringify(fromBson, undefined, undefined, { relaxed: false });
const backToBson = EJSON.parse(ejsonFromBson, { relaxed: false });
// Perfect round-trip fidelity
console.log(original._id.equals(backToBson._id)); // trueExtended JSON v1 format is supported for backwards compatibility:
import { EJSON } from "bson";
const document = { count: Long.fromNumber(42) };
// Extended JSON v2 (default)
const v2 = EJSON.stringify(document);
// { "count": { "$numberLong": "42" } }
// Extended JSON v1 (legacy)
const v1 = EJSON.stringify(document, undefined, undefined, { legacy: true });
// { "count": { "$numberLong": 42 } } // Note: number instead of string