BigInt — Arbitrary Precision Integers
debt(d9/e3/b3/t7)
Closest to 'silent in production until users hit it' (d9). JSON.parse() silently corrupts large integers — the value changes without any error or warning. Two different user IDs can become identical with no runtime exception, no linter warning (detection_hints.tools is empty and no standard tool catches this), and no compiler signal. The corruption only surfaces when users experience incorrect behavior.
Closest to 'simple parameterised fix' (e3). The quick_fix describes a small but two-sided change: serialize IDs as strings on the PHP server side and parse them as BigInt on the client. This is a localized pattern replacement across a boundary (server serialization + client parsing), slightly more than a one-liner but contained within a single data-flow concern.
Closest to 'localised tax' (b3). Once the string-ID convention is adopted for large integers, the burden is limited to the specific data paths that handle those IDs. Other parts of the codebase are largely unaffected. However, BigInt's incompatibility with Math functions, JSON.stringify, and mixed arithmetic means any code touching those IDs pays a small ongoing tax.
Closest to 'serious trap' (t7). The misconception is that 'using BigInt everywhere instead of Number is safer,' but BigInt cannot represent fractional numbers and breaks Math functions, JSON serialization, and mixed arithmetic. More critically, the opposite trap — not using BigInt for large IDs — causes silent data corruption that contradicts the intuitive expectation that JSON round-trips are lossless. This contradicts how similar numeric handling works in most other languages.
Also Known As
TL;DR
Explanation
JavaScript uses IEEE 754 double-precision floating point for all numbers — integers above 2⁵³ lose precision. The number 9007199254740993 and 9007199254740994 are represented identically. BigInt literals use an 'n' suffix: 9007199254740993n. BigInt supports all arithmetic operators (+, -, *, **, /, %) and comparison operators but cannot be mixed with regular Number in arithmetic — you must explicitly convert. BigInt cannot be serialized to JSON natively (JSON.stringify throws a TypeError). It is not available in very old browsers but has broad support since 2020. PHP's int type is 64-bit on 64-bit systems, so PHP can natively handle numbers that JavaScript's Number cannot.
Watch Out
Common Misconception
Why It Matters
Common Mistakes
- JSON.parse() silently corrupting large integers — JSON has no BigInt type; numbers parse as IEEE 754 doubles. Use string IDs or a custom JSON parser.
- JSON.stringify() throwing on BigInt — add a replacer: JSON.stringify(data, (k, v) => typeof v === 'bigint' ? v.toString() : v).
- Mixing BigInt with Math functions — Math.max(), Math.sqrt() etc. do not accept BigInt; convert to Number first (with possible precision loss).
- Not checking browser support — BigInt requires Chrome 67+, Firefox 68+, Safari 14+; polyfilling is complex and usually not worth it.
Code Examples
// ❌ Large integer loses precision in JSON
// PHP sends: {"id": 9007199254740993}
// JS receives:
const data = JSON.parse('{"id": 9007199254740993}');
console.log(data.id); // 9007199254740992 — wrong!
console.log(data.id === 9007199254740993); // false
// ❌ Mixing BigInt and Number
const a = 100n;
const b = 50;
const c = a + b; // TypeError: Cannot mix BigInt and other types
// ✅ Server sends ID as string, client parses as BigInt
// PHP: json_encode(['id' => (string) $largeId])
const data = JSON.parse('{"id": "9007199254740993"}');
const id = BigInt(data.id); // 9007199254740993n — correct
// BigInt arithmetic
const a = 9007199254740993n;
const b = 100n;
console.log(a + b); // 9007199254741093n
// Convert back to string for API calls
fetch(`/api/users/${id.toString()}`);
// Comparison works across types with ==
console.log(10n == 10); // true
console.log(10n === 10); // false (different types)