Skip to main content
CuteJSON
↑↓ Navigate Enter Select Esc Close

JSON data types explained, with the edge cases that break parsers

Published 4 min read By Akash Kinkar Pandey

JSON has exactly six value types: string, number, boolean, null, array and object. Nothing in the specification adds a seventh. That short list is easy to state and surprisingly easy to get wrong in practice, mostly at the edges each type has that a language’s own native types do not share.

String

Text in double quotes, never single quotes. 'hello' is not valid JSON, only "hello" is. A handful of characters need escaping inside a string: the quote itself (\"), a backslash (\\), and the control characters \n, \r, \t, \b and \f. Anything else, including most Unicode text, can go in unescaped as long as the file itself is valid UTF-8. JSON Escape and Unescape handles the conversion in both directions and reports exactly which character broke a malformed escape sequence, rather than a generic parse error.

Number

One numeric type, not separate integer and float types the way some languages have. A JSON number is a sequence of digits, an optional decimal point, and an optional exponent: 42, -3.14, 2.5e10. No hexadecimal, no Infinity, no NaN, and no leading zero before a non-zero digit (0123 is invalid, 0.123 is fine). The sharpest edge here: JavaScript’s own Number type is a 64-bit float, which cannot represent every integer past about 2^53 (nine quadrillion or so) exactly. Parse a JSON document containing a 64-bit database ID or a Snowflake ID with JSON.parse in a browser console and the tail digits can come back rounded, silently. The JSON Formatter on this site is built on a token stream rather than JSON.parse specifically so a twenty digit integer survives a round trip unrounded, and reports the numbers it could not represent safely rather than rounding without saying so.

Boolean

Exactly two literal values, lowercase, unquoted: true and false. "true" is a string, not a boolean, and a common source of bugs when a field that should be a boolean gets serialized as text somewhere upstream.

Null

One literal value, lowercase, unquoted: null. It represents the deliberate absence of a value, which is a different thing from a key that is missing entirely. {"middleName": null} says “this person has no middle name, and we checked.” A document without a middleName key at all says nothing about whether one exists. APIs that conflate the two (using a missing key and a null value interchangeably) make that distinction impossible to recover on the receiving end.

Array

An ordered list, [ ], comma separated, elements of any type including mixed types in the same array: [1, "two", true, null] is valid JSON even though it would be an odd choice of schema. Order is guaranteed and significant; two arrays with the same elements in a different order are different values.

Object

An unordered set of key-value pairs, { }, keys always strings (even a numeric-looking key like "2" is a string, not a number), values any type. Two keys with the same name inside one object is not forbidden by the grammar, though the specification calls the behavior “not recommended” and leaves what happens next up to the parser; most implementations, including JSON.parse, silently keep the last one and discard the earlier ones. The JSON Validator flags a duplicate key as a warning rather than letting a document with one pass silently, since which value survives is the kind of thing that should be an explicit decision.

What none of the six types can hold

No date type: a timestamp is a string, almost always ISO 8601 ("2026-08-24T10:00:00Z"), by convention rather than by anything JSON itself enforces. No undefined: a key that would be undefined in JavaScript is omitted from the object rather than written with that value, since JSON has no literal for it at all. No functions, no Map or Set, no comments anywhere in the document. A format that needs any of those (configuration with inline comments, for instance) is choosing a different format on purpose, not a JSON extension; see JSON vs YAML for the tradeoff that comment support and a few other conveniences carry with them.

Trying it

Paste any document into the JSON Viewer and each value’s type gets its own color and badge in the tree, which is a fast way to see exactly how a document is typed without reading the raw text character by character. For the syntax rules in one glance, see the JSON Cheat Sheet.

Back to all posts