{ }jsonkitOpen the tool

JSON Data Types Explained (with Examples)

8 min read · updated 2026-07-12

JSON looks simple, and its type system genuinely is: there are only six data types, and no way to define your own. But that simplicity hides a handful of rules that trip up experienced developers — no NaN, no trailing commas, no comments, no native date type, and integer precision that quietly breaks past a certain size.

This guide walks through all six JSON data types with runnable examples, shows how each maps to JavaScript and Python, and covers the gotchas that actually cause bugs: big-integer precision loss, dates smuggled in as strings, and the difference between null and a missing key. To eyeball a payload's structure as you read, paste it into the JSON Formatter.

The Six JSON Data Types at a Glance

The JSON specification (defined by ECMA-404 and RFC 8259) recognizes exactly six value types. Every valid JSON value is one of these — there is no seventh, and no mechanism to register custom types. Two are structural (object and array); four are primitives.

TypeExampleCategory
string"hello"primitive
number42, -3.14, 6.02e23primitive
booleantrue, falseprimitive
nullnullprimitive
object{ "id": 1 }structural
array[1, 2, 3]structural

A JSON document as a whole is a single value — most often an object or array, but a bare string or number is technically valid JSON too. Everything else you might reach for (dates, sets, functions, undefined, big integers, binary blobs) has to be encoded on top of these six primitives, usually as a string. That constraint is the source of most JSON surprises, so it is worth internalizing early.

A single object containing an example of every typejson
{
  "name": "Ada",
  "age": 36,
  "active": true,
  "nickname": null,
  "roles": ["admin", "editor"],
  "address": { "city": "London", "zip": "EC1A" }
}

Strings, Numbers, Booleans, and Null

Strings

A JSON string is a sequence of Unicode characters wrapped in double quotes. Single quotes are never allowed — a common mistake for developers coming from Python or JavaScript. Certain characters must be escaped with a backslash: the double quote (\"), the backslash itself (\\), and control characters like newline (\n), tab (\t), and carriage return (\r). Any character can also be written as a \uXXXX Unicode escape.

Pasting a string that contains quotes or newlines into a JSON field by hand makes escaping easy to get wrong. The JSON Escape / Unescape tool handles it both ways, and How to Escape and Unescape JSON Strings covers the rules in depth.

Numbers

JSON numbers are base-10 and cover both integers and floats in one type — the format itself has no separate int/float distinction. You can use a leading minus sign, a decimal point, and scientific notation (1.5e-9). What you cannot use: leading zeros (007), a leading plus sign, hexadecimal (0xFF), or a trailing decimal point.

Booleans and null

Booleans are the bare lowercase literals true and false — never quoted, never capitalized. null is its own distinct type representing an intentional absence of value. It is the only value of its type, and it is different from a key being absent entirely (more on that below).

Objects and Arrays: Structure and Nesting

Objects

An object is an unordered collection of key/value pairs wrapped in curly braces. Keys must be strings in double quotes — numbers or bare identifiers as keys are invalid. Values can be any of the six types, which is what makes JSON recursive. The spec does not forbid duplicate keys, but their behavior is undefined; most parsers keep the last one. Treat duplicate keys as a bug.

Arrays

An array is an ordered list of values in square brackets. Unlike arrays in statically typed languages, JSON arrays are heterogeneous — one array can mix strings, numbers, objects, and even more arrays. Order is significant and preserved by every conformant parser.

Nesting and a mixed-type arrayjson
{
  "users": [
    { "id": 1, "tags": ["a", "b"] },
    { "id": 2, "tags": [] }
  ],
  "mixed": [1, "two", true, null, { "k": "v" }, [9, 8]]
}

The spec sets no hard nesting limit, but parsers impose practical depth limits to prevent stack overflows, and deeply nested structures are hard to read. When a payload gets unwieldy, the JSON Formatter will indent it so the nesting is visible at a glance.

What JSON Deliberately Leaves Out

Much of what makes JSON confusing is what it does not have. Knowing the omissions upfront saves debugging time:

  • No date or time type. Dates are conventionally encoded as ISO 8601 strings ("2026-07-12T14:30:00Z"). The parser sees a plain string and will not revive it into a date object for you.
  • No comments. // and /* */ are not valid JSON. For commented config, reach for JSON5, JSONC, or NDJSON, not JSON.
  • No `undefined`. JavaScript's undefined is not a JSON value. JSON.stringify drops object keys whose value is undefined and turns undefined array elements into null.
  • No integer/float distinction, no BigInt. There is one number type and no way to mark a value as an integer versus a decimal.
  • No trailing commas, no single quotes, no hex or octal. The grammar is strict.
  • No binary type. Binary data is typically Base64-encoded into a string.

Because these constraints are enforced by the grammar rather than by convention, a quick pass through a JSON Validator will catch violations before they reach your application.

How JSON Types Map to JavaScript and Python

JSON's type names come from JavaScript, so the JS mapping is nearly one-to-one. Python's json module maps types just as cleanly, with a few naming differences.

JSONJavaScriptPython
stringstringstr
numbernumberint or float
booleanbooleanbool (True / False)
nullnullNone
objectobject (plain)dict
arrayArraylist

Python decides between int and float when parsing a number based on whether a decimal point or exponent is present, whereas JavaScript funnels every number into a single IEEE-754 double. Also mind the casing when writing JSON by hand in Python: JSON uses lowercase true/false/null, not Python's True/False/Nonejson.dumps handles the translation for you.

Round-tripping every JSON type through Python's json modulepython
import json

data = {
    "name": "Ada",
    "age": 36,
    "score": 9.5,
    "active": True,
    "nickname": None,
    "roles": ["admin", "editor"],
}

text = json.dumps(data)          # dict -> JSON string
restored = json.loads(text)      # JSON string -> dict

print(type(restored["age"]))     # <class 'int'>
print(type(restored["score"]))   # <class 'float'>
print(restored["active"])        # True
print(restored["nickname"])      # None

For the full API on both sides, see Working with JSON in JavaScript and Working with JSON in Python.

Gotchas: Big Integers, Dates, and null vs Missing

Integer precision loss

JSON itself imposes no limit on the size of a number, but most parsers read numbers into a 64-bit IEEE-754 double, which represents integers exactly only up to 2^53 − 1 (9,007,199,254,740,991). Larger integers — 64-bit database IDs, snowflake IDs, some blockchain values — get silently rounded. This is a real, hard-to-spot data-corruption bug.

A large integer ID is corrupted on parsejs
const raw = '{ "id": 9007199254740993 }';
const parsed = JSON.parse(raw);

console.log(parsed.id); // 9007199254740992  <-- wrong, rounded down

// The fix: keep the value as a string end to end
const safe = JSON.parse('{ "id": "9007199254740993" }');
console.log(safe.id); // "9007199254740993"  <-- exact

Dates are just strings

Since JSON has no date type, standardize on ISO 8601 in UTC ("2026-07-12T14:30:00Z"). It sorts lexicographically in chronological order, is unambiguous about time zone, and every language can parse it. Avoid locale-specific formats like 07/12/2026, and note that JSON.stringify(new Date()) produces an ISO string but JSON.parse will not turn it back into a Date — you have to revive it yourself.

null vs a missing key

{ "nickname": null } and {} are not the same thing. The first explicitly states the nickname is known to be empty; the second says nothing about nickname at all. This distinction matters for PATCH-style APIs, where null often means "clear this field" while an absent key means "leave it unchanged." In JavaScript both reads yield a falsy value, so check with "nickname" in obj or Object.hasOwn(obj, "nickname") when the difference is meaningful. When diffing two payloads to see whether a key vanished or merely became null, a structural JSON Diff makes it obvious.

Validate and Inspect Your JSON

Types are easiest to reason about when the document is properly indented and confirmed well-formed. Format a raw payload to reveal its structure, then, if you need machine-enforced type rules across many documents, describe the expected shape with a schema.

{ }JSON FormatterOpen the tool

To lock down which types each field is allowed to hold — for example, requiring age to be an integer and email to be a string matching a pattern — define a schema. JSON Schema: A Complete Guide walks through it, and you can bootstrap one from a sample payload with the generator below.

§JSON Schema GeneratorOpen the tool

Frequently asked questions

How many data types does JSON have?

JSON has exactly six data types: string, number, boolean, null, object, and array. Object and array are structural (they can contain other values), while string, number, boolean, and null are primitives. You cannot define custom types.

Does JSON have a date or datetime type?

No. JSON has no native date type. Dates are conventionally encoded as strings, ideally in ISO 8601 UTC format like "2026-07-12T14:30:00Z". The parser treats them as plain strings, so you must convert them to a date object yourself after parsing.

Why does my large number lose precision in JSON?

Most JSON parsers read numbers into a 64-bit IEEE-754 double, which represents integers exactly only up to 2^53 − 1 (9,007,199,254,740,991). Larger integers get rounded. Transmit big IDs as strings and convert on the consuming side to preserve every digit.

Can JSON numbers be NaN or Infinity?

No. NaN, Infinity, and -Infinity are not valid JSON, even though they are valid IEEE-754 floats. JavaScript's JSON.stringify converts them to null, and Python's json.dumps emits invalid tokens unless you set allow_nan=False. Sanitize these values before serializing.

What is the difference between null and a missing key in JSON?

A key set to null ("nickname": null) explicitly states the value is empty, while a missing key says nothing about that field at all. This matters for PATCH APIs, where null often means "clear the field" and an absent key means "leave it unchanged." Check membership with the in operator or Object.hasOwn.

How do JSON types map to Python types?

JSON string maps to str, number to int or float (depending on whether it has a decimal point or exponent), boolean to bool, null to None, object to dict, and array to list. The json module handles the conversion in both directions via json.loads and json.dumps.