Skip to content

Bug: numberToCurrency crashes due to bignumber.js v10 browser bundle incompatibility #126

@impe93

Description

@impe93

Bug Report

Summary

numberToCurrency (and any method relying on formatNumber) throws a TypeError when used in bundled environments (React Native with Metro, Webpack, Parcel, etc.) and bignumber.js resolves to v10.x.

The issue does not occur in plain Node.js, where the "main" field is used for module resolution. It only affects bundlers that resolve the "browser" field in package.json.

Environment

  • i18n-js: 4.5.3 (also reproducible with 4.3.2 and latest)
  • bignumber.js: 10.0.2 (resolved via "bignumber.js": "*" in i18n-js dependencies)
  • Bundler: Metro (React Native), likely also Webpack/Parcel in browser builds

Steps to Reproduce

  1. Set up a React Native project (or any project using a bundler that resolves the "browser" field)
  2. Install i18n-js
  3. Let yarn/npm resolve bignumber.js: "*" to v10.x
  4. Call numberToCurrency:
const i18n = new I18n();
i18n.numberToCurrency(1500);
  1. The call throws a TypeError.

Note: This works correctly in plain Node.js because Node resolves the "main" field instead of "browser".

Root Cause

  1. bignumber.js v10 introduced a "browser" field in its package.json: "browser": "dist/bignumber.js"
  2. This browser bundle is an IIFE that assigns BigNumber to the global scope instead of using module.exports: (typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : self).BigNumber = BigNumber;
  3. Bundlers that resolve the "browser" field (Metro, Webpack, Parcel) load this file. Since it never sets module.exports, require('bignumber.js') returns an empty object {}.
  4. In parseBigNumber.js, the call (0, bignumber_js_1.default)(NaN) attempts to invoke {} as a function → TypeError.

bignumber.js v9.x did not have a "browser" field, so bundlers fell back to the "main" field (dist/bignumber.cjs) which correctly uses module.exports = BigNumber.

Workaround

Pin bignumber.js to v9.x in the project's package.json resolutions:

"resolutions": {
    "bignumber.js": "^9.0.0"
}

Then reinstall dependencies and clear bundler cache.

Suggested Fix

The "bignumber.js": "*" wildcard dependency in i18n-js's package.json allows any major version to be installed, including v10 which introduced this breaking change. Possible fixes:

  1. Pin bignumber.js to ^9.0.0 in i18n-js's package.json to prevent v10 from being resolved.
  2. Alternatively, update parseBigNumber.js and formatNumber.js to handle the case where the "browser" bundle of bignumber.js does not export via CommonJS (e.g., fall back to globalThis.BigNumber), though this would be fragile.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions