--- title: Encoding and decoding JavaScript BigInt values with reviver date: 2021-08-11 updated_at: 2021-08-13 layout: post lang: en ref: encoding-and-decoding-javascript-bigint-values-with-reviver --- `JSON.parse()` accepts a second parameter: a [`reviver()` function][reviver]. It is a function that can be used to transform the `JSON` values as they're being parsed. [reviver]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#using_the_reviver_parameter As it turns out, when combined with JavaScript's [`BigInt`] type, you can parse and encode JavaScript `BigInt` numbers via JSON: [`BigInt`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt ```javascript 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: ```javascript 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: ```javascript 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: ``` [ 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. [`JSON`]: https://datatracker.ietf.org/doc/html/rfc8259