Encoding and decoding JavaScript BigInt values with reviver

Posted on August 11, 2021
Updated on August 13, 2021

JSON.parse() accepts a second parameter: a reviver() function. It is a function that can be used to transform the JSON values as they’re being parsed.

As it turns out, when combined with JavaScript’s BigInt type, you can parse and encode JavaScript BigInt numbers via JSON:

1
2
3
4
const bigIntReviver = (_, value) =>
	typeof value === "string" && value.match(/^-?[0-9]+n$/)
		? BigInt(value.slice(0, value.length - 1))
		: value;

I chose to interpret strings that contains only numbers and an ending n suffix as BigInt values, similar to how JavaScript interprets 123 (a number) differently from 123n (a bigint);

We do those checks before constructing the BigInt to avoid throwing needless exceptions and catching them on the parsing function, as this could easily become a bottleneck when parsing large JSON values.

In order to do the full roundtrip, we now only need the toJSON() counterpart:

1
2
3
BigInt.prototype.toJSON = function() {
	return this.toString() + "n";
};

With both bigIntReviver and toJSON defined, we can now successfully parse and encode JavaScript objects with BigInt values transparently:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const s = `[
	null,
	true,
	false,
	-1,
	3.14,
	"a string",
	{ "a-number": "-123" },
	{ "a-bigint": "-123n" }
]`;

const parsed = JSON.parse(s, bigIntReviver);
const s2 = JSON.stringify(parsed);

console.log(parsed);
console.log(s2);

console.log(typeof parsed[6]["a-number"])
console.log(typeof parsed[7]["a-bigint"])

The output of the above is:

1
2
3
4
5
6
7
8
9
10
11
12
13
[
  null,
  true,
  false,
  -1,
  3.14,
  'a string',
  { 'a-number': '-123' },
  { 'a-bigint': -123n }
]
[null,true,false,-1,3.14,"a string",{"a-number":"-123"},{"a-bigint":"-123n"}]
string
bigint

If you’re on a web browser, you can probably try copying and pasting the above code on the console right now, as is.

Even though JSON doesn’t include BigInt number, encoding and decoding them as strings is quite trivial on JavaScript.