{"id":10580,"library":"bn.js","title":"BN.js: Arbitrary-Precision Big Numbers","description":"bn.js is a fundamental pure JavaScript library providing a comprehensive implementation for arbitrary-precision integers, commonly referred to as \"Big Numbers.\" It is currently at version 5.2.3 and maintains an active release cadence, frequently addressing bug fixes and minor improvements, as seen in recent updates like v5.2.1 and v5.2.0. A key design principle is its focus on integer arithmetic; it explicitly does not support decimal numbers, which is an important consideration for users. Differentiating features include support for in-place operations (e.g., `iadd`), unsigned operations (e.g., `umod`), and operations that take native JavaScript numbers as arguments (e.g., `addn`), allowing for performance optimizations and flexible usage patterns. It provides a wide array of utilities, arithmetic, and bitwise operations crucial for cryptographic applications, large financial calculations, and other domains requiring precision beyond standard JavaScript `Number` limits.","status":"active","version":"5.2.3","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/indutny/bn.js","tags":["javascript","BN","Big number","BigNum","Modulo","Montgomery"],"install":[{"cmd":"npm install bn.js","lang":"bash","label":"npm"},{"cmd":"yarn add bn.js","lang":"bash","label":"yarn"},{"cmd":"pnpm add bn.js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"bn.js primarily ships as a CommonJS module. While modern bundlers or TypeScript with `esModuleInterop` enabled might allow `import BN from 'bn.js'`, the canonical way, especially in Node.js, is `require`. For TypeScript without `esModuleInterop`, `import * as BN from 'bn.js'` is often recommended.","wrong":"import BN from 'bn.js';","symbol":"BN","correct":"const BN = require('bn.js');"},{"note":"Static methods like `isBN` are properties of the main `BN` object, not named exports from the package root. The library exports `BN` as the module's default export.","wrong":"import { isBN } from 'bn.js';","symbol":"BN.isBN","correct":"const BN = require('bn.js');\nconst isBN = BN.isBN;"},{"note":"The `Red` context (for Montgomery reduction) is accessed via the `BN.red()` static method, passing a prime or a BN instance. This is not a direct import.","symbol":"Red","correct":"const BN = require('bn.js');\nconst Red = BN.red('k256');"}],"quickstart":{"code":"const BN = require('bn.js');\n\n// Initialize Big Numbers from various bases\nconst hexValue = new BN('DEADBEEF', 16);\nconst binValue = new BN('10101010101010101010', 2);\n// Decimal numbers can be large strings, exceeding standard JS Number limits\nconst decValue = new BN('123456789012345678901234567890');\n\nconsole.log('Initialized from Hex:', hexValue.toString(16));\nconsole.log('Initialized from Binary:', binValue.toString(2));\nconsole.log('Initialized from large Decimal String:', decValue.toString(10));\n\n// Perform arithmetic operations\nlet sum = hexValue.add(binValue);\nconsole.log('\\nSum (hexValue + binValue) in decimal:', sum.toString(10));\n\nlet product = decValue.mul(new BN(2)); // Multiply by another BN instance\nconsole.log('Product (decValue * 2):', product.toString(10));\n\n// Demonstrate in-place operation: `a.iadd(b)` modifies `a`\nlet a = new BN('100', 10);\nlet b = new BN('50', 10);\na.iadd(b); \nconsole.log('In-place addition (a.iadd(b)), \"a\" is now:', a.toString(10)); // Should be 150\n\n// Demonstrate unsigned modulo with negative numbers\nlet negative = new BN('-10');\nlet modulo = new BN('3');\nconsole.log('Signed modulo (-10 mod 3):', negative.mod(modulo).toString(10)); // Expected: -1\nconsole.log('Unsigned modulo (-10 umod 3):', negative.umod(modulo).toString(10)); // Expected: 2 ((-10 % 3) + 3)\n\n// Convert to different formats (e.g., Buffer, Array)\n// Requires Node.js Buffer to be available in the environment for toBuffer\ntry {\n  const buffer = hexValue.toBuffer('be', 4); // Big-endian, 4 bytes padded\n  console.log('Buffer representation of hexValue (hex string):', buffer.toString('hex'));\n} catch (e) {\n  console.log('Buffer operations skipped (Buffer class might not be available in this environment).');\n}\n\n// Check if an object is a BN.js instance\nconsole.log('\\nIs hexValue a BN instance?', BN.isBN(hexValue));\nconsole.log('Is a plain number a BN instance?', BN.isBN(123));","lang":"javascript","description":"This quickstart demonstrates how to initialize `BN` objects from various bases and large strings, perform basic arithmetic and bitwise operations including in-place and unsigned variants, and convert `BN` instances to different output formats. It also shows how to check if an object is a `BN` instance."},"warnings":[{"fix":"Ensure all string inputs to the `BN` constructor represent integers without decimal points. For example, use `new BN('123', 10)` instead of `new BN('123.45', 10)` (which is not supported).","message":"Since `v5.0.0`, the BN constructor enforces stricter input validation, specifically rejecting decimal numbers when passed as a string. It expects pure integer strings matching the specified base.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Replace `.modn()` with `.mod()` or `.umod()`, ensuring the modulus argument is also a `BN` instance if it's not a small JavaScript Number (which can be used with `modn` like alternatives).","message":"The `.modn()` method was deprecated in `v5.0.0` and should no longer be used.","severity":"deprecated","affected_versions":">=5.0.0"},{"fix":"If decimal precision is required, consider using alternative libraries like `bignumber.js` or `decimal.js`. Ensure all inputs and operations are strictly integer-based when using BN.js.","message":"BN.js is designed exclusively for integer arithmetic. It does not support decimal numbers or floating-point operations anywhere in the library.","severity":"gotcha","affected_versions":"all"},{"fix":"For `BN` values exceeding 53 bits, use `.toString(10)` for full decimal representation, or `.toArray()`, `.toBuffer()` for byte representations. Avoid `.toNumber()` for cryptographic keys, hashes, or large financial amounts.","message":"The `.toNumber()` method can only safely convert `BN` instances to JavaScript `Number` primitives if their value fits within 53 bits (equivalent to `Number.MAX_SAFE_INTEGER`). Larger values will lose precision or result in incorrect numbers.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure all `bn.js` installations within a project are consistent at `v5.1.2` or later to avoid mixing major versions and their internal differences.","message":"There were interoperability issues when mixing `bn.js` v4 and v5 instances, leading to potential unexpected behavior in shared codebases.","severity":"gotcha","affected_versions":"5.0.0 - 5.1.1"},{"fix":"Upgrade to `bn.js@5.2.1` or newer to ensure correct hexadecimal string conversions. Verify critical output if upgrading is not immediately possible.","message":"Versions prior to `v5.2.1` contained a serious bug in the `.toString(16)` method, potentially producing incorrect hexadecimal string representations.","severity":"gotcha","affected_versions":"<5.2.1"},{"fix":"For JavaScript `Number` arguments exceeding `0x4000000`, convert the number into a `BN` instance first (e.g., `new BN(largeNum)`) and then use the corresponding method without the `n` suffix (e.g., `bnInstance.iadd(new BN(largeNum))`).","message":"Methods with the `n` postfix (e.g., `iaddn`, `muln`) which accept a plain JavaScript `Number` argument, have an upper limit of `0x4000000` (67,108,864) for that argument. Providing a larger number will throw a `RangeError`.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure all string inputs to the `BN` constructor are pure integer representations matching the provided base (e.g., `new BN('10', 10)` is valid, `new BN('10.5', 10)` is not).","cause":"Attempting to initialize a BN instance with a string containing non-integer parts (e.g., decimals) or characters invalid for the specified base, especially after v5.0.0's stricter validation.","error":"Error: not that many bits (or similar for invalid input)"},{"fix":"Replace `bnInstance.modn(num)` with `bnInstance.mod(new BN(num))` or, for unsigned results, `bnInstance.umod(new BN(num))`. Alternatively, if `num` is a small JavaScript number, use `bnInstance.mod(new BN(num))` or `bnInstance.modn` alternatives for specific contexts if available in newer versions (refer to documentation).","cause":"Attempting to use the `.modn()` method, which was deprecated and removed in `v5.0.0`.","error":"TypeError: BN.modn is not a function"},{"fix":"For values larger than `Number.MAX_SAFE_INTEGER`, use `.toString(10)` to get the full decimal string representation. Other conversion methods like `.toArray()` or `.toBuffer()` can provide byte-level access without numeric precision limits.","cause":"Calling `.toNumber()` on a BN instance that holds an integer value greater than `Number.MAX_SAFE_INTEGER` (2^53 - 1), leading to precision loss or an incorrect result.","error":"RangeError: Number can only safely store up to 53 bits (or incorrect numerical output from toNumber())"},{"fix":"For number arguments greater than `0x4000000`, convert the JavaScript `Number` into a `BN` instance first (e.g., `new BN(largeNum)`) and then use the corresponding method without the `n` suffix (e.g., `bnInstance.iadd(new BN(largeNum))`).","cause":"A JavaScript `Number` argument passed to an `n`-suffixed method (e.g., `iaddn`, `muln`) exceeds the maximum allowed value of `0x4000000` (67,108,864).","error":"RangeError: n must be less than 0x4000000"}],"ecosystem":"npm"}