Lodash _.toSafeInteger() method

Beginner
⏱️ 6 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • What “safe integer” means in IEEE-754 terms: ±(2⁵³ − 1).
  • How _.toSafeInteger composes _.toInteger with a clamp.
  • Why Infinity becomes MAX_SAFE_INTEGER and -Infinity becomes its negative.
  • How it differs from _.toInteger and _.toLength (different windows!).

Prerequisites

You’ve finished the _.toInteger tutorial; this method is the same truncation plus a magnitude clamp.

  • You know that JavaScript numbers can’t losslessly distinguish integers above 2⁵³.
  • Try-it labs load lodash from the CDN.

Overview

One line of implementation: return value ? _.clamp(_.toInteger(value), −2⁵³+1, 2⁵³−1) : 0. The output is always an integer you can compare and arithmetic on without IEEE-754 surprises.

Symmetric window

Negatives allowed (±9 007 199 254 740 991).

No NaN / Infinity

Falsy and NaN0; ±Infinity±MAX_SAFE_INTEGER.

Inherits parsing

Trims whitespace; parses hex/binary/octal via _.toNumber.

Syntax

javascript
_.toSafeInteger(value)
  • value: the value to convert.
  • Returns: a signed integer in [−(2⁵³−1), 2⁵³−1]. Never NaN or ±Infinity.
1

Lodash docs baseline

The four official examples—decimal, sub-1, infinity, numeric string.

javascript
import toSafeInteger from "lodash/toSafeInteger";

console.log(
  "3.2:             " + toSafeInteger(3.2) + "\n" +                          // 3
  "MIN_VALUE:       " + toSafeInteger(Number.MIN_VALUE) + "\n" +             // 0
  "Infinity:        " + toSafeInteger(Infinity) + "\n" +                      // 9007199254740991
  "'3.2' string:    " + toSafeInteger("3.2")                              // 3
);
Try it Yourself
2

Clamping at ±MAX_SAFE_INTEGER

The window is symmetric. Anything past the edge gets snapped back to it—negatives included.

javascript
import toSafeInteger from "lodash/toSafeInteger";

const huge = Number.MAX_SAFE_INTEGER + 5;     // already lossy as a Number
const negHuge = -Number.MAX_SAFE_INTEGER - 5;

console.log(
  "MAX_SAFE_INTEGER:        " + toSafeInteger(Number.MAX_SAFE_INTEGER) + "\n" +  // 9007199254740991
  "MAX_SAFE_INTEGER + 5:    " + toSafeInteger(huge) + "\n" +                      // 9007199254740991
  "-MAX_SAFE_INTEGER - 5:   " + toSafeInteger(negHuge) + "\n" +                   // -9007199254740991
  "-Infinity:               " + toSafeInteger(-Infinity)                          // -9007199254740991
);
Try it Yourself
3

Strings, nullish, & numeric prefixes

Parsing inherits from _.toNumber_.toFinite_.toInteger: trim, hex/binary/octal, “bad input → 0.”

javascript
import toSafeInteger from "lodash/toSafeInteger";

console.log(
  "'-3.2' string: " + toSafeInteger("-3.2") + "\n" +      // -3
  "' 7 ' trim:     " + toSafeInteger(" 7 ") + "\n" +        // 7
  "'0x1f' hex:     " + toSafeInteger("0x1f") + "\n" +       // 31
  "'abc':          " + toSafeInteger("abc") + "\n" +        // 0
  "null:           " + toSafeInteger(null) + "\n" +          // 0
  "NaN:            " + toSafeInteger(NaN)                     // 0
);
Try it Yourself

📋 _.toSafeInteger vs related conversions

Input_.toSafeInteger_.toInteger_.toLength
3.7333
-5-5-50
NaN000
Infinity90071992547409911.79e+3084294967295
1e2090071992547409911e+204294967295
-Infinity-9007199254740991-1.79e+3080

Pitfalls to avoid

Precision

Input may already be lossy

Numeric literals like 9007199254740993 can’t be represented exactly—your call site has already lost precision before _.toSafeInteger sees them. For arbitrary-precision IDs, use BigInt and strings.

Direction

Truncation toward zero

Inherits _.toInteger’s behavior. _.toSafeInteger(-1.5) is -1 (not -2). Use Math.floor if you really want floor.

BigInt

BigInt throws

_.toSafeInteger(1n) raises “Cannot convert a BigInt value to a number.” Convert with Number(bigint) first if you can accept truncation.

❓ FAQ

From −9,007,199,254,740,991 to +9,007,199,254,740,991 (±(2^53 − 1)). That's the largest magnitude JavaScript can represent without precision loss between consecutive integers.
Same truncation toward zero, but with an additional clamp to [−MAX_SAFE_INTEGER, MAX_SAFE_INTEGER]. So _.toInteger(1e20) returns 1e20 (unsafe), while _.toSafeInteger(1e20) returns 9007199254740991.
_.toLength clamps to [0, 2^32 − 1] (array length range). _.toSafeInteger allows negatives and a much larger upper bound.
Never. Infinity becomes ±9,007,199,254,740,991; NaN becomes 0; BigInt throws 'Cannot convert a BigInt value to a number'.

Summary

  • Purpose: guarantee an integer that JavaScript can store and compare without IEEE-754 precision loss.
  • Remember: truncation toward zero, clamp to ±(2⁵³−1), falsy → 0.
  • Next: head to Lodash _.toString()_.toString wraps up the conversion family.
Did you know?

_.toSafeInteger’s window is ±(2⁵³ − 1) = ±9 007 199 254 740 991—the largest magnitude IEEE-754 doubles can hold without losing precision between consecutive integers. Past 2⁵³, even adding 1 can return the same number you started with.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful