Number.MIN_SAFE_INTEGER
Holds the smallest integer JavaScript can represent exactly, -(2^53 - 1).
Number.MIN_SAFE_INTEGER- Added in JavaScript ES2015
Return value
numberThe number -9007199254740991, that is -(2^53 - 1). The property is non-writable, non-enumerable and non-configurable.
Errors
Nothing on read; assigning to it throws a TypeError in strict mode, because the property is non-writable.
This is the exact mirror of Number.MAX_SAFE_INTEGER: doubles use a sign bit plus a 53-bit significand, so the negative side of the safe range is the same width as the positive side. Everything from -(2**53 - 1) up to 2**53 - 1 has its own representation; below this constant, integers start skipping and equality becomes unreliable.
When to reach for it
It closes the lower half of a range check. A test for a usable integer id or counter is normally written as both bounds together, and Number.isSafeInteger() is the built-in version of exactly that pair of comparisons. It is also the natural seed for a running maximum over integers that may all be negative — though Number.NEGATIVE_INFINITY is the safer seed, because it also loses to non-integers.
What trips people up
People reach for this when they want the most negative number JavaScript can hold. That is -Number.MAX_VALUE, roughly -1.8e308 — nearly three hundred orders of magnitude further out. This constant is only about integers that stay exact.
Like its positive twin, crossing it produces no error. Number.MIN_SAFE_INTEGER - 1 and Number.MIN_SAFE_INTEGER - 2 both evaluate to -9007199254740992 and compare equal, so a loop counting downward past the boundary simply stops making progress in a way nothing reports.
Example
When to use it
- Validating that a signed id or offset from an external system is still exact.
- Writing an explicit range guard: n >= Number.MIN_SAFE_INTEGER && n <= Number.MAX_SAFE_INTEGER.
- Detecting when a decrementing counter or negative accumulator needs to move to BigInt.
Frequently asked questions
What is the most negative number in JavaScript?
-Number.MAX_VALUE, about -1.7976931348623157e+308, is the most negative finite number; Number.NEGATIVE_INFINITY lies below it. Number.MIN_SAFE_INTEGER is much closer to zero and only marks where integers stop being exact.
Is Number.MIN_SAFE_INTEGER the same as -Number.MAX_SAFE_INTEGER?
Yes, they are exactly equal, both -9007199254740991. Doubles carry a separate sign bit, so the safe integer range is symmetric around zero.
What happens if I subtract past Number.MIN_SAFE_INTEGER?
Nothing visible: the result rounds to the nearest representable double, so MIN_SAFE_INTEGER - 1 and MIN_SAFE_INTEGER - 2 are both -9007199254740992 and compare equal. Use Number.isSafeInteger() or BigInt if you need the difference to stay exact.
More examples
An explicit two-sided range guard
The three checks written out are precisely what Number.isSafeInteger() does, which the last line confirms. -1e17 is a perfectly ordinary finite number but sits well below the lower bound, so it fails; 1.5 fails on the integer test rather than the range test.
function inSafeRange(n) {
return Number.isInteger(n)
&& n >= Number.MIN_SAFE_INTEGER
&& n <= Number.MAX_SAFE_INTEGER;
}
console.log(inSafeRange(-42)); // true
console.log(inSafeRange(-1e17)); // false - past the lower bound
console.log(inSafeRange(1.5)); // false - not an integer
console.log(inSafeRange(-1e17) === Number.isSafeInteger(-1e17)); // trueThe lower bound is not the smallest number
Three constants people confuse. MIN_SAFE_INTEGER is the exactness boundary; -MAX_VALUE is the actual finite floor, far lower; MIN_VALUE is a tiny positive number near zero and has nothing to do with negatives. Only NEGATIVE_INFINITY sits below -MAX_VALUE.
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
console.log(-Number.MAX_VALUE); // -1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324 (positive!)
console.log(-Number.MAX_VALUE < Number.MIN_SAFE_INTEGER); // true
console.log(Number.NEGATIVE_INFINITY < -Number.MAX_VALUE); // true
Discussion