JSON Data Types
The seven value types JSON supports, the ones it deliberately omits, and how each maps into the language you are working in.
Seven Types, and That Is All
JSON's type system is deliberately tiny. A value is exactly one of these:
{
"aString": "hello",
"aNumber": 42,
"anObject": { "nested": true },
"anArray": [1, 2, 3],
"isTrue": true,
"isFalse": false,
"nothing": null
}You will see this counted as six types or seven depending on the source. The grammar treats true and false as two separate literals rather than one boolean type, so the honest answer is seven values across six conceptual categories. Nothing rests on which way you count.
What matters far more is what is not in that list — no date, no decimal, no binary, no set. Most real-world JSON friction comes from representing those absences.
Strings
A sequence of Unicode characters in double quotes. Single quotes are never valid, for keys or values.
"hello"
"with \"escaped\" quotes"
"line one\nline two"
"emoji work fine: 🎉"
"unicode escape: \u00e9 is the same as é"Strings are where JSON puts everything it has no dedicated type for — dates, UUIDs, decimals, enumerated values, Base64 blobs. That makes strings the most overloaded type in practice, and the reason a schema is often necessary to say what a given string actually represents. Escaping rules are covered on the escaping page.
Numbers
One numeric type, covering everything. There is no separate integer and float.
0 -1 3.14 1e10 1.5e-8 -0.5Two properties of this type cause most of the trouble with it.
Precision is an implementation concern, not a grammar one. JSON's syntax places no limit on digits, but nearly every parser stores numbers as 64-bit floats. Integers past 253 — about 9 quadrillion — are silently rounded:
JSON.parse('{"id": 12345678901234567890}').id
// → 12345678901234567000 ← corrupted, with no error raisedPython is a notable exception, since its integers have unlimited precision — which means a Python service can be correct while a JavaScript client consuming the same payload quietly corrupts it. Send large IDs as strings.
Money should never be a JSON number. Binary floating point cannot represent most decimal fractions exactly, so 0.1 + 0.2 famously does not equal 0.3. Use a string ("19.99") parsed into a decimal type, or an integer count of minor units (1999 cents) with the scale documented.
Objects and Arrays
The two container types, and the source of JSON's ability to describe nested structures of any shape.
{ "key": "value", "nested": { "deeper": [1, 2] } }
[ "a", "b", { "mixed": true } ]The important distinction between them is ordering. Arrays are ordered and that ordering is guaranteed — position carries meaning and every parser preserves it. Objects are unordered by specification. Most parsers happen to preserve document order, and Python and modern JavaScript both do, but nothing in the standard requires it, so code that depends on key order is relying on an accident.
Arrays may hold mixed types, and usually should not. An array whose elements have different shapes forces every consumer to type-check each item, which is a design smell rather than a feature. See JSON arrays and JSON objects for detail.
Booleans and null
true, false and null are lowercase literals, always. Python developers hand-editing JSON write True and None from muscle memory; both are syntax errors.
null deserves more thought than it usually gets, because it is not the same as an absent key:
{ "middleName": null } // known to have no middle name
{ } // middle name not providedFor a PATCH request the difference is decisive — null means "clear this field", omission means "leave it as it is". APIs that treat the two identically cannot express "clear this field" at all. Decide which semantics you want and document it, because clients cannot guess.
Representing What JSON Lacks
Four types you will need constantly and JSON does not provide. These are the established conventions:
| Concept | Convention | Example |
|---|---|---|
| Date / time | ISO 8601 string, UTC | "2026-08-07T14:30:00Z" |
| Money / decimal | String, or integer minor units | "19.99" or 1999 |
| Binary | Base64 string | "iVBORw0KGgo…" |
| Large integer ID | String | "12345678901234567890" |
Always use UTC with an explicit Z for timestamps. A local time without an offset is ambiguous, and the ambiguity surfaces as an off-by-hours bug during a daylight-saving transition — months after the code was written.
How Types Map Across Languages
| JSON | JavaScript | Python | Go |
|---|---|---|---|
| object | Object | dict | map / struct |
| array | Array | list | slice |
| string | string | str | string |
| number | number | int / float | float64 |
| true / false | boolean | True / False | bool |
| null | null | None | nil |
Two rows repay attention. Python splits number into int and float with unlimited integer precision, so it is the one mainstream language that will not corrupt a huge ID. Go collapses every number to float64 when decoding into interface, reintroducing the same precision loss — unless you decode into a typed struct field or call UseNumber().
Frequently Asked Questions
How many data types does JSON have?
Seven, though they are often counted as six. The value types are string, number, object, array, true, false and null. Because true and false are separate literals in the grammar rather than one boolean type, the count depends on whether you group them.
Why does JSON have no date type?
Dates are genuinely hard to standardise — time zones, calendars, leap seconds and precision all vary by use case. JSON's designer kept the type set minimal deliberately. The universal convention is to transmit dates as ISO 8601 strings such as "2026-08-07T14:30:00Z".
Does JSON distinguish integers from floats?
No. There is a single number type, so 1 and 1.0 are both simply numbers. Many serialisers collapse 1.0 to 1, which matters if the receiving system is type-sensitive. Languages with separate int and float types make the distinction on their side, not JSON's.
How do I send binary data in JSON?
Encode it as a Base64 string. JSON has no binary type and strings must be valid Unicode, so raw bytes cannot be embedded. Base64 costs roughly 33% in size, so for anything large prefer a separate upload with a URL in the JSON.
What is the difference between null and an absent key?
null is an explicit value meaning 'known to be nothing'. An absent key means 'not provided'. They are genuinely different — a PATCH request setting a field to null means 'clear this', while omitting it means 'leave it alone'. Many APIs conflate the two and create ambiguity as a result.