BigInt is a JavaScript primitive (standardized in ES2020) that can represent integers with arbitrary precision, unlike the Number primitive, which can only safely store integer values up to Number.MAX_SAFE_INTEGER (2<sup>53</sup> - 1). BigInt lets applications work with integers that do not fit into the safe Number integer range. Applications do not have to worry about integer overflow when performing integer arithmetic with BigInt.
For example, with a BigInt, an application can represent the following number with 949 digits:
1981736304199322413033155801017007660571991838127382513183869502655132945955410381978047930657291929328288215
0606361136148620102904441975725292592628559967812484675646892511846918611620611557168971934110225307415064349
8363325492215252179814608914978848514521148286358193185975317403169331562554772751601328737118172997857019565
4412014954799861023018894168724656416695879451586197508165521397945043501171786040218486867988008752171425034
1196327155439333794638153206641651301969127462864035534874455812703397724619751741504170473595816399761522130
0466851042618062726302177752344216671603543132982051584234733113584510328373733271849956633295642753394057746
2921547661536249039107602105847940990310966177991999680511207851623398036926020603299101758654216200328207217
0802170818128446172076808512000167514374118804496410628196099710910975151856288299881083251368933286107688452
87219627992142295849162918727812831234961883883469929500772200319747415930309n
One application area that depends on big-number arithmetic is cryptography.
If you use a back-end language that supports a 64-bit data type like Java with long, BigInt allows a JavaScript
application to safely represent these values on the client (for example, primary keys or timestamps in nanoseconds).
Implementations and Standard ¶
BigInt is part of the ES2020 standard. As of 2026, it is broadly supported in all modern JavaScript engines (Chrome, Firefox, Safari, Edge, Node.js, and Deno).
Babel 7 and TypeScript 3.2+ support BigInt syntax and type checking. Keep in mind that transpilers cannot polyfill native BigInt operator behavior in engines that do not implement BigInt.
Syntax ¶
To differentiate a BigInt from a Number, append the letter n to the end of the numeric literal.
For example, 156 is a Number, 156n is a BigInt.
You can convert a Number to a BigInt with the global BigInt(number) function.
const literal = 11n;
const aNumber = 156;
const converted = BigInt(aNumber);
converted === 156n // true
BigInts can also be written with binary, octal, or hexadecimal notation:
const h = 0x100n;
// h === 256n
const o = 0o064n;
// o === 52n
const b = 0b10101010101n;
// b === 1365n
When used as a boolean, BigInt follows the same rule as a Number. 0n is falsy.
if (0n) {
console.log('truthy');
} else {
console.log('falsy');
}
// prints "falsy"
The typeof operator used with a BigInt returns "bigint":
typeof 156;
// "number"
typeof 156n;
// "bigint"
Operators ¶
BigInt supports the same operators as Number in most cases and works as expected.
20 - 3 * 4 ** 2 / (3 % 4) === 4
20n - 3n * 4n ** 2n / (3n % 4n) === 4n
/ and % round towards zero:
6n / 7n === 0n
7n / 6n === 1n
Most bitwise operators also work like they do with Numbers:
128 << 3
// 1024
128n << 3n
// 1024n
Not supported is the >>> operator because BigInts are signed.
128n >>> 3n
// Uncaught TypeError: BigInts have no unsigned right shift, use >> instead
The unary - operator can be used to denote a negative BigInt:
const a = -156n
The unary + operator is not supported with BigInts because it would cause a problem with asm.js,
which expects the unary + operator always to return a Number.
const b = +6
b === 6
const c = +6n
// Uncaught TypeError: Cannot convert a BigInt value to a number
There is one limitation to be aware of: you cannot mix Number and BigInt. The JavaScript engine throws an exception if you try to do that.
const d = 45 + 10n
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
The JavaScript engine cannot implicitly convert Number and BigInt because
BigInt does not support fractions, and Number can only represent integers safely up to 2<sup>53</sup> - 1.
Conversion to and from Number ¶
You can always explicitly convert with the global functions BigInt() and Number():
BigInt(45) + 10n === 55n
45 + Number(10n) === 55
parseFloat() and parseInt() can also convert a BigInt to a Number.
const a = parseFloat(100n);
// a === 100
const b = parseInt(101n);
// b === 101
You need to be cautious with conversions to Number. If you convert a BigInt that is outside the safe integer range (Number.MAX_SAFE_INTEGER, which is 2^53 - 1), Number(), parseFloat(), and parseInt() do not throw an error,
but the Number they return is not able to represent the integer correctly.
If the BigInt is greater than Number.MAX_VALUE, these three methods return Infinity.
const bi = 2n**56n;
// bi === 72057594037927936n
const n = Number(72057594037927936n);
// n === 72057594037927940
const large = 2n*10n**309n;
Number(large) === Infinity;
parseFloat(large) === Infinity;
Comparisons ¶
As mentioned before, you can't mix Numbers and BigInts in arithmetic expressions. There is one exception: comparison operators. These operators are allowed and return booleans.
10 == 10n
// true
10 === 10n
// false
9 < 10n
// true
9n > 10
// false
Conversion to and from strings ¶
The global BigInt() function can convert not only Numbers, but also strings, to BigInt values:
BigInt(10) === 10n;
BigInt('100') === 100n;
The function throws an exception if it cannot convert the provided value into a BigInt.
BigInt(23.5)
// RangeError: The number 23.5 cannot be converted to a BigInt because it is not an integer
BigInt('23.5')
// SyntaxError: Cannot convert 23.5 to a BigInt
BigInt values also have a toString() method that converts the value to a string:
const s = 100n.toString();
// s === "100"
The + operator can concatenate strings and BigInts, the same behavior we already know
from concatenating strings and Numbers.
const s1 = 'Amount: ' + 1;
// s1 === "Amount: 1"
const s2 = 'Amount: ' + 1n;
// s2 === "Amount: 1"
You can also use BigInts in template literals, with the same behavior you already know from Numbers.
const value = 123n;
const s3 = `Amount: ${value}`
// s3 === "Amount: 123"
JSON ¶
JSON does not support BigInt. If you try to convert a JavaScript object with a BigInt field to JSON, JavaScript throws an exception.
const obj = {name: 'test', value: 100n};
const j = JSON.stringify(obj);
// TypeError: Do not know how to serialize a BigInt
As a workaround, you can convert BigInts to either Numbers (if they fit into the supported range)
or to a string. JSON.stringify() supports a second parameter called a replacer, which we can use to write a generic function that converts all BigInts to strings.
const j = JSON.stringify(obj, (key, value) => {
if (typeof value === 'bigint') {
return value.toString() + 'n';
}
return value;
});
// j === '{"name":"test","value":"100n"}'
To parse such a JSON, we can pass a function as the second argument (reviver) to the JSON.parse()
method. This function is called for each key/value pair. It first checks whether the value is a string,
contains an optional minus sign plus digits, and ends with the letter n. If true, it passes the string to the BigInt constructor; otherwise, it returns the original value.
const obj2 = JSON.parse(j, (_key, value) => {
if (typeof value === 'string' && /^-?\d+n$/.test(value)) {
return BigInt(value.slice(0, -1));
}
return value;
});
// obj2 --> {name: "test", value: 100n}
Math ¶
For Number values, JavaScript provides a built-in Math object with properties and methods for mathematical constants and functions.
For BigInt, there is no dedicated built-in math object.
Many Math functions do not make sense for a number type without fractions, but a few operations could be useful for BigInt.
Fortunately, these are not that complicated to implement.
Here is a very trivial implementation of max, min, sign, abs, and sqrt:
class BigIntMath {
static max(...values) {
if (values.length === 0) {
return null;
}
if (values.length === 1) {
return values[0];
}
let max = values[0];
for (let i = 1; i < values.length; i++) {
if (values[i] > max) {
max = values[i];
}
}
return max;
}
static min(...values) {
if (values.length === 0) {
return null;
}
if (values.length === 1) {
return values[0];
}
let min = values[0];
for (let i = 1; i < values.length; i++) {
if (values[i] < min) {
min = values[i];
}
}
return min;
}
static sign(value) {
if (value > 0n) {
return 1n;
}
if (value < 0n) {
return -1n;
}
return 0n;
}
static abs(value) {
if (this.sign(value) === -1n) {
return -value;
}
return value;
}
// https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/58863398#58863398
static rootNth(value, k = 2n, limit = -1) {
if (value < 0n) {
throw new Error('negative number is not supported');
}
let o = 0n; // old approx value
let x = value;
while (x ** k !== value && x !== o && --limit) {
o = x;
x = ((k - 1n) * x + value / x ** (k - 1n)) / k;
if (limit < 0 && (x - o) ** 2n === 1n) {
break;
}
}
if ((value - (x - 1n) ** k) ** 2n < (value - x ** k) ** 2n) {
x = x - 1n;
}
if ((value - (x + 1n) ** k) ** 2n < (value - x ** k) ** 2n) {
x = x + 1n;
}
return x;
}
static sqrt(value) {
return BigIntMath.rootNth(value);
}
}
Usage:
const min = BigIntMath.min(1n,2n,3n,4n); // min == 1n
const max = BigIntMath.max(1n,2n,3n,4n); // max == 4n
const sign = BigIntMath.sign(-11n); // sign === -1n
const abs = BigIntMath.abs(-11n); // abs === 11n
const sqrt = BigIntMath.sqrt(81n); // sqrt === 9n
There is no need for a Math.pow() implementation for BigInt; we can use the exponentiation operator introduced in ECMAScript 2016.
const a = Math.pow(3,4);
// a === 81
const b = 3n ** 4n;
// b === 81n
Polyfills ¶
Because BigInt is a primitive, there is no way for a polyfill to implement the n syntax and add BigInt support
to built-in operators in engines that do not implement BigInt.
However, there are big integer libraries you can use when you need compatibility with legacy engines. The syntax looks different and is not as convenient as the built-in implementation. The performance is usually slower than the native implementation because these libraries run their calculations in JavaScript.
Google published a chart in its BigInt blog post comparing the native implementation with a few Big Integer libraries: https://v8.dev/features/bigint
The following example shows how you can do big integer arithmetic with the bn.js library.
You add the library like any other JavaScript library:
npm install bn.js
Then import it, create BN instances from strings or numbers, and use the provided methods.
import BN from 'bn.js';
const a = new BN('156');
const b = new BN(200);
const result = a.add(b);
// result.toString() === "356"
const b1 = new BN('90071992547409910000');
const b2 = new BN('29839283291982398238');
const r = b1.mul(b2);
// r.toString() === "2687683702295491619562538437047738580000"
The bn.js library provides a wide variety of methods. See the documentation on the GitHub project page: https://github.com/indutny/bn.js/
Many other libraries introduce big integer arithmetic to Node.js and the browser: