What is JSON?
On this page
JSON — JavaScript Object Notation — is a text-based data interchange format. It’s how nearly every API on the web sends structured data: a server returns JSON, your browser parses it, your app renders it. The format is simple, human-readable, and supported in every programming language.
This page is the practical introduction. For just formatting/validating JSON, jump straight to the formatter or validator.
The six value types
A JSON value is exactly one of these:
| Type | Examples |
|---|---|
| Object | {"name": "Alice", "age": 42} |
| Array | [1, 2, 3] |
| String | "hello" (always double quotes) |
| Number | 42, 3.14, -1.5e10 |
| Boolean | true or false |
| Null | null |
That’s it. There are no dates, no integers-vs-floats distinction, no bytes type, no comments. The simplicity is the point — a JSON parser fits in a few hundred lines of code in any language.
A complete example
{
"user": {
"id": "0e6f1b8c-2c33-4f1f-9c0b-2a3d4e5f6a7b",
"email": "alice@example.com",
"verified": true,
"createdAt": "2026-04-26T12:00:00Z",
"preferences": {
"theme": "dark",
"newsletter": false
},
"tags": ["admin", "early-access"]
}
}
This shows nearly everything: nested objects, an array, all primitive types, and the convention for representing dates as ISO 8601 strings (since JSON has no date type).
Where JSON came from
Doug Crockford specified JSON in the early 2000s as a subset of JavaScript syntax suitable for data interchange. The format quickly outgrew JavaScript — by 2010 it was the de facto standard for REST APIs, replacing XML in most web services.
The official specification is now RFC 8259 (December 2017), with the looser ECMA-404 standard covering the syntax. Both define the same format with minor differences in what “valid” means.
Why it won
- Human-readable. You can debug JSON by reading it. XML technically is too, but the angle brackets and namespaces make it hostile.
- JavaScript-native.
JSON.parse()andJSON.stringify()are built in to every browser. No library needed. - Lightweight. No schema required, no document declaration, no namespace boilerplate.
- Polyglot. Every language has a JSON library, often in the standard library.
- HTTP-friendly. Maps cleanly to REST resources; trivial to log and grep.
What JSON is NOT
- A schema. JSON describes data, not data types or constraints. For schemas, see JSON Schema.
- A query language. To select fields from JSON, you need JSONPath or
jq. - A binary format. Strings are UTF-8 (or escaped Unicode). Want binary? Use base64-encoded strings or switch to MessagePack / Protocol Buffers.
- Comment-friendly. JSON has no comment syntax. JSONC, JSON5, and Hjson add comments but are non-standard supersets.
- Streaming-friendly. JSON requires the whole document before you can parse. For streaming, see NDJSON / JSON Lines (one JSON value per line).
The gotchas every developer hits
1. Numbers don’t distinguish int from float
JSON has one numeric type: a 64-bit IEEE-754 double. Practical consequence: integers larger than 2⁵³ lose precision.
{ "id": 9007199254740993 }
This parses as 9007199254740992 in JavaScript — the trailing 3 becomes 2. Workarounds: send large IDs as strings (most APIs do), or use a parser that supports BigInt on the receiving side.
2. Strings are always double-quoted
{ 'name': 'Alice' } // ❌ INVALID — single quotes
{ name: "Alice" } // ❌ INVALID — unquoted key
{ "name": "Alice" } // ✅
JavaScript’s looser object syntax accepts the first two; JSON does not.
3. No trailing commas
{ "a": 1, "b": 2, } // ❌ INVALID
[1, 2, 3,] // ❌ INVALID
JSON5 and JSONC allow them; strict JSON does not.
4. No NaN, Infinity, or undefined
{ "x": NaN } // ❌ INVALID
{ "x": Infinity } // ❌ INVALID
{ "x": undefined } // ❌ INVALID — undefined is a JS-only value
If you have these in your data, encode as null or as a sentinel string.
5. Dates are strings
JSON has no date type. The conventional encoding is ISO 8601:
{ "createdAt": "2026-04-26T12:00:00Z" }
Every language’s standard library can parse this. Other formats (Unix epoch milliseconds as a number, RFC 2822 strings) work too — pick one and document it.
6. UTF-8, but the spec says UTF-16
Technically JSON is “Unicode text” and can be UTF-8, UTF-16, or UTF-32. In practice, everyone uses UTF-8 and parsers expect it. Set your Content-Type to application/json; charset=utf-8 and don’t worry about it.
7. Maps with integer keys
JSON objects only have string keys. If you want a map keyed by integers, you have to stringify them:
{ "1": "Alice", "2": "Bob" } // keys are strings, not numbers
This trips up languages where the runtime distinguishes the two (Python, Go’s map[int]string, etc.).
JSON tooling at the command line
# pretty-print
echo '{"a":1}' | jq .
# validate (exit 0 if valid)
echo "$INPUT" | jq empty
# extract a field
curl https://api.example.com/users/42 | jq '.email'
# filter an array
echo '[{"x":1},{"x":2}]' | jq '.[] | select(.x > 1)'
jq is the universal JSON Swiss Army knife at the shell. jp, gron, and fx are alternatives worth knowing.
In your language
// JavaScript / TypeScript — built-in
const obj = JSON.parse(text);
const text = JSON.stringify(obj, null, 2);
# Python — built-in
import json
obj = json.loads(text)
text = json.dumps(obj, indent=2)
// Go — encoding/json in stdlib
var v map[string]any
json.Unmarshal([]byte(text), &v)
out, _ := json.MarshalIndent(v, "", " ")
// Rust — serde_json crate
let v: serde_json::Value = serde_json::from_str(text)?;
let text = serde_json::to_string_pretty(&v)?;
When JSON is the wrong tool
- Binary data (images, audio): use the binary format directly. JSON-base64 wastes 33% of bandwidth.
- Multi-gigabyte data: streaming formats like Apache Arrow, Parquet, or NDJSON.
- Self-describing schemas with constraints: Protocol Buffers, Avro, or JSON Schema layered on top.
- Configuration files where comments matter: TOML, YAML, or JSONC.
- Wire protocols where bytes matter: MessagePack, CBOR, FlatBuffers.
For everything else — REST APIs, web app state, log aggregation, simple config — JSON is the boring correct answer.
Try the tools
- JSON formatter — paste, format, copy
- JSON minifier — strip whitespace
- JSON validator — check syntax
- JSON → YAML — convert formats
- JSON vs YAML — when to pick which
Related across the network
- jwt.tooljo.com — JWT payload is JSON. Decode any token to see what JSON it carries.
- regex.tooljo.com — pattern-match before full JSON parse for line-based filtering.
- json.tooljo.com/blog/ndjson-in-2026 — line- delimited JSON (ndjson / jsonlines) for streaming workloads.