What Is JSON?
JSON stands for JavaScript Object Notation, a lightweight, text-based data interchange format derived from JavaScript object literal syntax. Despite its JavaScript origins, JSON is language-independent: every major programming language has built-in or widely-used library support for parsing and generating JSON.
JSON was popularised by Douglas Crockford in the early 2000s as a simpler alternative to XML for web API data exchange. It is now formalised in two complementary standards: RFC 8259 (the definitive IETF standard) and ECMA-404 (the minimal, formal specification).
Six Data Types
JSON defines exactly six data types:
- null — represents absence of value:
null - boolean —
trueorfalse - number — IEEE 754 double-precision floating-point:
42,3.14,-7,1.5e10 - string — UTF-8 text in double quotes:
"hello","café","line1\nline2" - array — ordered sequence of values:
[1, "two", null, true] - object — unordered collection of key-value pairs:
{"key": "value", "n": 42}
Everything in JSON is built from these six types. There is no concept of dates, binary data, undefined, functions, regular expressions, or comments.
Syntax Rules
{
"name": "Alice",
"age": 30,
"active": true,
"score": 98.6,
"tags": ["admin", "editor"],
"address": {
"street": "123 Main St",
"city": "Springfield",
"zip": "12345"
},
"nickname": null
}
Strict syntax requirements:
- Keys must be strings (double-quoted)
- Strings must use double quotes (single quotes are invalid)
- Trailing commas are invalid (no comma after the last element)
- Comments are invalid (not part of the JSON spec)
- Numbers cannot have leading zeros (
01is invalid) - Numbers cannot be
NaNorInfinity
These restrictions make JSON easy to parse unambiguously but frustrating to write by hand when compared to more permissive formats.
String Escaping
Within JSON strings, certain characters must be escaped with a backslash:
| Character | Escape sequence |
|---|---|
" |
\" |
\ |
\\ |
/ |
\/ (optional; for embedding in HTML) |
| Backspace | \b |
| Form feed | \f |
| Newline | \n |
| Carriage return | \r |
| Tab | \t |
| Unicode | \uXXXX (4-hex-digit) |
Unicode characters outside the Basic Multilingual Plane (code points U+10000 and above) must be encoded as surrogate pairs:
𝄞(U+1D11E, G-clef) →𝄞
Modern JSON parsers handle all of this automatically. The \uXXXX encoding is only necessary when the character cannot be included directly in the document encoding.
Number Precision
JSON numbers map to IEEE 754 double-precision floating-point, which has 53 bits of significand precision. This causes a well-known problem: integers larger than 2^53 (9,007,199,254,740,992) cannot be represented exactly.
{"id": 9007199254740993}
A JavaScript JSON.parse() will parse 9007199254740993 as 9007199254740992 — off by one, silently. This is why Twitter, Facebook, and many APIs return large integer IDs as both a number and a string: {"id": 1234567890123456789, "id_str": "1234567890123456789"}.
JSON Schema
JSON Schema is a vocabulary for validating and describing JSON documents, defined by IETF drafts (no final RFC yet). It allows specifying constraints like:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0, "maximum": 150},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "age"]
}
JSON Schema enables automated validation, IDE auto-complete, API contract testing, and documentation generation. Tools: ajv (JavaScript), jsonschema (Python), networknt/json-schema-validator (Java).
JSON5 and JSONC Extensions
Because JSON's strict syntax frustrates configuration file authors, several extensions have emerged:
JSON5: A superset of JSON allowing:
- Single-line comments (
// ...) - Multi-line comments (
/* ... */) - Trailing commas
- Single-quoted strings
- Unquoted object keys (if valid identifiers)
- Hexadecimal numbers (
0xFF) - Leading/trailing decimal points (
.5,5.) - Multi-line strings (backslash-continued)
JSONC (JSON with Comments): Allows // and /* */ comments but nothing else. Used by VS Code's settings.json, TypeScript's tsconfig.json, etc. Not parseable by standard JSON parsers.
JSON vs XML vs YAML
| Feature | JSON | XML | YAML |
|---|---|---|---|
| Human readability | Good | Verbose | Excellent |
| Data types | 6 native | Text only (attributes typed via Schema) | Rich (dates, binary, null) |
| Comments | No | Yes | Yes |
| Schema validation | JSON Schema | XSD, DTD, RelaxNG | No standard |
| Binary support | No (base64) | No (base64) | Yes (!!binary) |
| Namespace support | No | Yes | No |
| Query language | JSONPath, jq | XPath, XQuery | — |
| Streaming parse | Yes (SAX-style) | Yes (SAX) | Limited |
| File size | Compact | Verbose | Compact |
| API usage | Dominant | Legacy/SOAP | Config files |
| Parsing complexity | Very low | Medium | High (edge cases) |
Common JSON Patterns
API response envelope:
{
"status": "success",
"data": {
"users": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
},
"meta": {
"total": 2,
"page": 1,
"per_page": 10
}
}
GeoJSON (geographic data):
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.9857, 40.7484]
},
"properties": {
"name": "Empire State Building"
}
}
JSON Lines (JSONL) — one JSON object per line, for streaming and log files:
{"id": 1, "event": "login", "ts": "2024-01-15T10:30:00Z"}
{"id": 2, "event": "purchase", "ts": "2024-01-15T10:31:00Z"}
Processing JSON
Command line (jq):
# Extract all names from an array of objects
cat data.json | jq '.[].name'
# Filter objects where age > 25
cat data.json | jq '[.[] | select(.age > 25)]'
# Convert JSON to CSV
cat data.json | jq -r '["name","age"], (.[] | [.name, .age]) | @csv'
Python:
import json
# Parse JSON string
data = json.loads('{"name": "Alice", "age": 30}')
print(data['name']) # Alice
# Serialize to JSON string
json_str = json.dumps(data, indent=2, ensure_ascii=False)
# Read/write files
with open('data.json') as f:
data = json.load(f)
with open('output.json', 'w') as f:
json.dump(data, f, indent=2)
Converting JSON
JSON → CSV: Works when JSON is an array of flat objects (no nested objects). jq -r, csvkit's in2csv, or pandas json_normalize.
JSON → XML: Structure must be mapped (JSON arrays → repeated XML elements; keys → tag names or attributes). Libraries: xmltodict (Python), json2xml, XSLT transforms.
JSON → YAML: Nearly lossless for most data since YAML is a superset of JSON. python -c "import json, yaml, sys; yaml.dump(json.load(sys.stdin), sys.stdout)".
JSON → SQL: Requires schema mapping; jq + psql COPY, or pandas json_normalize + to_sql.
Summary
JSON is the lingua franca of modern web APIs, configuration files, and data interchange. Its six-type data model, strict syntax, and text-based format strike a balance between human-readability and machine-parseability. Key limitations — no comments, no native date type, no binary, integer precision cap at 2^53 — are well-known and worked around. For configuration files needing comments, JSON5 or JSONC are practical extensions; for data with complex hierarchies, XML adds namespace and schema features; for human-authored configs, YAML is most readable. JSON itself dominates everything in between.
Related conversions
Document conversions that follow this topic naturally: