JSON has one number type, and it's a float
JSON numbers map onto IEEE 754 double-precision floats. There is no separate integer type in the spec; 5 and 5.0 are the same value. Most parsers preserve the integer/float distinction internally, but the spec doesn't require it.
Syntax rules
- No leading zeros —
007is invalid; write7. - No
+on positive numbers —+5is invalid; write5. - Decimal point requires digits on both sides —
.5and5.are invalid; write0.5and5.0. - Scientific notation OK —
1e6,1.5e-3,2E10all valid. - NaN and Infinity are NOT allowed — encode as
null, or as a tagged string by convention.
The 253 precision cliff
JS numbers (and most JSON parsers) lose integer precision above Number.MAX_SAFE_INTEGER (= 253 - 1 = 9,007,199,254,740,991). A 64-bit Twitter ID, a Stripe object ID, or a database BIGINT can silently round if you let it pass through a JS or default JSON parser. Send big integers as strings.
The Twitter ID bug: Twitter's API returns 64-bit tweet IDs. For a decade, naïve JS clients silently corrupted IDs above 253. Twitter's docs eventually told everyone to read
id_str instead of id. APIs that send big integers as JSON numbers are landmines — assume strings unless documented otherwise.