jsguides

Number.parseInt()

Number.parseInt(string, radix)

Number.parseInt() parses a string argument and returns an integer of the specified radix. It was added in ES2015 (ES6) as part of the modularization of the global parseInt, and it is the same function object under a different name.

Number.parseInt === parseInt; // true

If you’ve used parseInt() before, you already know how Number.parseInt() behaves. The qualified form just makes the call site read as a number conversion and avoids accidental shadowing from a local variable named parseInt.

Syntax

Number.parseInt(string)
Number.parseInt(string, radix)

Parameters

  • string — The value to parse. The argument is coerced to a string via String() coercion, so numbers, booleans, and other primitives are accepted as long as their string form is parseable. Leading and trailing whitespace in the resulting string is ignored.
  • radix (optional) — An integer between 2 and 36 that specifies the numeral base. When omitted, or when 0 is passed, the radix defaults to 10, except that a string starting with 0x or 0X is interpreted as base 16. The legacy “leading 0 = octal” rule from pre-ES5 engines no longer applies.

Return value

An integer parsed from the leading numeric prefix of string in the given radix. Returns NaN when:

  • The radix is outside [2, 36]
  • The first non-whitespace character cannot be converted to a number in that radix
  • The string is empty or contains no parsable prefix

Number.parseInt() does not throw on bad input — invalid arguments simply yield NaN.

Relationship to the global parseInt

Number.parseInt and the global parseInt are the same function. ES2015 added the qualified form so the Number namespace could host number-conversion utilities, mirroring the way Array and Object were already organized. There is no behavioral difference — pick whichever reads better at the call site.

// All three references resolve to the same function
const a = Number.parseInt;
const b = parseInt;
const c = globalThis.parseInt;
a === b && b === c; // true

The qualified form is worth preferring in a few specific cases:

  • When a local variable named parseInt might exist (from a bundler, an eval scope, or a library export), Number.parseInt won’t collide with it.
  • When a style guide or linter rule (ESLint’s radix, for example) wants the namespace explicit.
  • When reading the code, Number.parseInt makes “this returns a number” obvious without checking the function’s docs.

For everything else, the two forms are interchangeable.

Examples

Always pass an explicit radix. The ESLint radix rule enforces this, and it removes a whole class of “what base is this in?” bugs.

// Decimal parsing with an explicit radix
Number.parseInt("42", 10);          // 42
Number.parseInt("  42  ", 10);      // 42 (whitespace ignored)
Number.parseInt("-42", 10);         // -42
Number.parseInt("+42", 10);         // 42

// Hex strings
Number.parseInt("0xF", 16);         // 15
Number.parseInt("0xF");             // 15 (0x prefix implies radix 16)
Number.parseInt("F", 16);           // 15
Number.parseInt("F");               // NaN (defaults to radix 10)

Other bases work the same way — the radix simply tells the parser which digit alphabet to use. The digits 0 through 9 are always valid; a through z (case-insensitive) stand in for the values 10 through 35, which is why base 16 can read ff and base 36 can read z (the value 35). Picking a base is really just picking which character set the parser is allowed to consume.

Number.parseInt("1010", 2);         // 10 (binary)
Number.parseInt("17", 8);           // 15 (octal)
Number.parseInt("ff", 16);          // 255
Number.parseInt("z", 36);           // 35

The radix must be an integer in the closed interval [2, 36]. Any value outside that range — 1, 37, or even NaN — makes the call return NaN, regardless of how clean the string looks. The one exception is undefined, which is treated as “missing” and falls back to the default radix of 10 (or 16 if the string starts with 0x or 0X).

Number.parseInt() reads as many characters as it can from the start of the string, then stops at the first one that doesn’t fit the radix. The next block demonstrates that prefix behavior alongside the NaN cases, including the 0xF + radix 2 trap where the hex prefix is present but the radix is binary.

// Stops at first non-digit
Number.parseInt("123abc", 10);      // 123
Number.parseInt("3.14", 10);        // 3 (NOT 3.14)
Number.parseInt(" 3.14 ", 10);      // 3

// NaN cases
Number.parseInt("hello", 10);       // NaN
Number.parseInt("", 10);            // NaN
Number.parseInt("0xF", 2);          // NaN (radix=2, "x" is not a binary digit)

// Invalid radix
Number.parseInt("10", 1);           // NaN (radix must be >= 2)
Number.parseInt("10", 37);          // NaN (radix must be <= 36)
Number.parseInt("10", NaN);         // NaN
Number.parseInt("10", undefined);   // 10 (treated as missing)

Common gotchas

It is not a general number parser. "3.14" returns 3, not 3.14. If you need a float, use Number() or Number.parseFloat(). This is the single most common parseInt bug — someone trying to convert a decimal string and silently losing the fractional part.

Trailing junk is silently truncated. Number.parseInt("123abc", 10) returns 123 with no warning. If you’re parsing user input where this matters, validate the string first (regex, a schema, or a round-trip check) instead of trusting parseInt to reject bad input.

Empty and whitespace-only strings return NaN. Don’t fall into the “falsy on failure” trap — NaN is falsy, but 0 is also falsy, and Number.parseInt("0", 10) returns 0 (a successful parse). Use Number.isNaN(Number.parseInt(x, 10)) to check for parse failure.

It does not round and does not respect locale. Number.parseInt("99.999", 10) is 99 (truncation, not rounding). Number.parseInt("1,234", 10) is 1, because the parser stops at the comma. For locale-aware parsing, use Intl.NumberFormat or strip the separators first.

BigInt arguments throw. Number.parseInt(1n, 10) throws TypeError: Cannot mix BigInt and other types, use explicit conversions — the exception comes from the string-coercion step, not from parseInt itself. Coerce the BigInt to a string first if you need this.

Here is how the gotchas above play out side by side, so you can see exactly where Number.parseInt, Number.parseFloat, and Number diverge on the same input. Comparing them in one place is usually faster than remembering the rules for each function separately.

// Float vs integer parsing
Number.parseInt("3.14", 10);     // 3
Number.parseFloat("3.14");       // 3.14
Number("3.14");                  // 3.14

// Trailing junk tolerance
Number.parseInt("123abc", 10);   // 123
Number.parseFloat("123abc");     // 123
Number("123abc");                // NaN

// Empty string
Number.parseInt("", 10);         // NaN
Number.parseFloat("");           // NaN
Number("");                      // 0

// Locale separators
Number.parseInt("1,234", 10);    // 1
Number.parseFloat("1,234");      // 1
Number("1,234");                 // NaN

Number.parseInt vs Number() vs Number.parseFloat

A quick decision table:

InputNumber.parseInt(x, 10)Number(x)Number.parseFloat(x)
"42"424242
"3.14"33.143.14
"42px"42NaN42
""NaN0NaN
nullNaN0NaN
undefinedNaNNaNNaN
"0xF"151515
" 7 "777

The three functions overlap but don’t substitute for each other. Use Number.parseInt when you specifically want an integer in a known base. Use Number when you want the strictest conversion and NaN on trailing junk. Use Number.parseFloat when you want a float and don’t mind trailing junk.

A practical use case

The most common real-world reason to reach for Number.parseInt() is parsing a number that comes glued to a unit suffix, the way CSS or DOM measurements often do. The prefix parse is exactly what you want there: read the leading digits, ignore the rest.

// Pull the leading integer from a CSS-ish length
function parsePx(value) {
  const n = Number.parseInt(value, 10);
  return Number.isNaN(n) ? 0 : n;
}

parsePx("12px");     // 12
parsePx("-4px");     // -4
parsePx("0.5em");    // 0  (truncates the decimal)
parsePx("auto");     // 0  (NaN falls back to 0)
parsePx("");         // 0  (empty string → NaN → 0)

Notice how the guard against NaN matters even when the input is well-formed: the fallback is 0, but parsePx("0px") legitimately returns 0, and Number.isNaN is the only way to tell those apart from a parse failure.

See Also

  • parseInt() — the global parseInt, which is the same function
  • Number.parseFloat() — companion method for parsing floats
  • Number.isNaN() — the standard way to check whether a parseInt result was a parse failure