Why Do Web3 Applications Need BigNumber?

How Should We Handle Precision Issues in JavaScript?

đź§  Background: JavaScript Precision Limitation

JavaScript's native Number type is a 64-bit floating point number (IEEE 754). This limits its integer precision to 2^53 - 1, or about 9e15. Beyond that, numbers get rounded and lose accuracy.

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(9007199254740991 + 1);    // 9007199254740992 âś…
console.log(9007199254740991 + 2);    // 9007199254740992 ❌ precision loss

đź’° Why This Is a Problem in Web3

  • Ethereum (and other EVM chains) use wei as the smallest unit of ETH.

  • 1 ETH = 10^18 wei → sending just 1 ETH involves manipulating a big integer, far beyond JS safe integer range.

  • Smart contracts return values in wei, making it unsafe to use regular Number for balances, gas, token supply, etc.

âś… Solution: Use BigNumber or BigInt

To safely handle large numbers in Web3 apps, you must use arbitrary-precision number types, like:

  • ethers.BigNumber (from ethers.js)

  • BigNumber.js (arbitrary precision lib)

  • Native BigInt (ES2020)

  • web3.utils.BN (if using web3.js)

Example (using ethers.js):

import { parseEther, formatEther } from 'ethers'; 
const amountInWei = parseEther('1.0'); // returns BigNumber of 10^18 console.log(amountInWei.toString()); // '1000000000000000000' 
const readable = formatEther(amountInWei); // back to human-readable ETH console.log(readable); // '1.0'

đź§Ş Common Pitfall: Converting BigNumber to JS Number

Avoid this unless you're 100% sure the value is within the safe range:

const unsafe = BigNumber.from("1000000000000000000"); console.log(unsafe.toNumber()); // May throw or round incorrectly if too large

Instead, use:

console.log(unsafe.toString()); // Safe

đź’ˇ When to Use BigInt?

If you don’t need compatibility with libraries like ethers.js, and you’re just doing arithmetic:

const a = BigInt("1000000000000000000"); 
const b = BigInt("3000000000000000000"); 
const c = a + b; 
console.log(c.toString()); // "4000000000000000000"

But be careful: BigInt ≠ Number, and you can’t mix them.


đź§© Summary: Why BigNumber is Essential in Web3

ReasonExplanation✅ PrecisionJS Number can't represent large wei values accurately💡 CompatibilityWeb3 libraries return balances and values as BigNumber🔒 SafetyPrevent silent rounding bugs in balances, gas, etc.🛠️ ToolsUse parseEther, formatUnits, BigNumber.from, etc.