What Is JSON?
JSON (JavaScript Object Notation) is a lightweight, text-based data interchange format derived from JavaScript object literal syntax. Defined by Douglas Crockford in the early 2000s and standardized as ECMA-404 (2013) and RFC 8259 (2017), JSON has become the universal language of APIs, configuration files, and structured data exchange.
JSON's appeal is its simplicity: it has exactly 6 data types, 2 structural types, and a grammar that fits on one page — yet it can represent arbitrarily complex nested data structures. Every modern programming language has built-in JSON parsing, and the format is both human-readable and machine-parseable without special tools.
JSON Syntax
Complete Type System
Value types:
"string" ← quoted Unicode string
42 ← number (integer or float)
3.14 ← number (floating point)
1.5e10 ← number (scientific notation)
true ← boolean
false ← boolean
null ← null (absence of value)
Structural types:
{"key": "value"} ← object (key-value pairs)
[1, 2, 3] ← array (ordered list)
JSON Grammar Rules
-
Strings: Must use double quotes (not single quotes). Backslash escapes:
\",\\,\/,\b,\f,\n,\r,\t,\uXXXX(Unicode escape). -
Numbers: No leading zeros (except for
0itself). No trailing decimal point. No special values (Infinity, NaN are not valid JSON). -
Objects: Keys must be strings (double-quoted). Key-value pairs separated by commas. Trailing commas not allowed. Duplicate keys: undefined behavior (avoid).
-
Whitespace: Ignored between tokens (spaces, tabs, newlines, carriage returns).
-
No comments: JSON has no comment syntax. Workarounds: use a
_commentkey, use JSONC, or strip comments before parsing.
Well-Formed JSON Example
{
"user": {
"id": 12345,
"name": "Jane Smith",
"email": "jane@example.com",
"age": 34,
"premium": true,
"lastLogin": null,
"roles": ["admin", "editor"],
"preferences": {
"theme": "dark",
"notifications": false,
"language": "en-US"
},
"scores": [98.5, 87.3, 92.1],
"address": {
"street": "123 Main St",
"city": "Springfield",
"zip": "12345",
"country": "US"
}
}
}
JSON Schema Validation
JSON Schema (json-schema.org, Draft 2020-12) defines the expected structure of JSON documents:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"type": "object",
"required": ["id", "name", "email"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"roles": {
"type": "array",
"items": {
"type": "string",
"enum": ["admin", "editor", "viewer"]
},
"uniqueItems": true
}
},
"additionalProperties": false
}
Validation in Code
import jsonschema
import json
schema = json.load(open('user.schema.json'))
data = json.load(open('user.json'))
try:
jsonschema.validate(data, schema)
print("Valid!")
except jsonschema.ValidationError as e:
print(f"Invalid: {e.message} at {e.json_path}")
# ajv-cli (Node.js)
npx ajv validate -s user.schema.json -d user.json
# jsonschema (Python)
python -m jsonschema -i user.json user.schema.json
JSON Variants
JSON5
JSON5 relaxes JSON's strictness for human-written configuration files:
- Single-line and multi-line comments allowed
- Trailing commas in objects and arrays
- Single-quoted strings
- Unquoted object keys (if valid identifiers)
- Multi-line strings (backslash line continuation)
- Hexadecimal numbers (0xFF)
- Special numeric values (Infinity, -Infinity, NaN)
Used by: Babel config files, ESLint (some versions), package.json5 tooling.
JSONC (JSON with Comments)
JSON5 subset that only adds comment support (single-line // and multi-line /* */). Used by VS Code settings.json and tsconfig.json.
NDJSON / JSON Lines
Newline-Delimited JSON — one JSON object per line, no enclosing array:
{"id":1,"name":"Alice","score":95.5}
{"id":2,"name":"Bob","score":87.3}
{"id":3,"name":"Carol","score":92.1}
Advantages: streamable (process one record at a time), appendable (no need to parse entire file to add a record), line-by-line grep/awk compatible. Standard for log streams, Elasticsearch bulk import, ETL pipelines.
GeoJSON
JSON standard for geographic data (RFC 7946):
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.4194, 37.7749]
},
"properties": {
"name": "San Francisco",
"population": 874961
}
}
Used by Leaflet, Mapbox, QGIS, and all modern mapping tools.
jq — The JSON Command-Line Processor
jq is the essential tool for JSON manipulation from the terminal:
# Pretty-print JSON
cat data.json | jq .
# Extract a field
jq '.user.name' data.json
# Extract from array
jq '.[0].name' users.json # first element
jq '.[] | .name' users.json # all names
# Filter
jq '.[] | select(.age > 30)' users.json
jq '.[] | select(.roles | contains(["admin"]))' users.json
# Transform (create new object)
jq '.[] | {name: .name, email: .email}' users.json
# Count items
jq '. | length' array.json
# Sort and unique
jq '[.[] | .country] | unique | sort' users.json
# Sum a field
jq '[.[] | .score] | add' users.json
# Output as CSV
jq -r '.[] | [.id, .name, .score] | @csv' users.json
Converting JSON
JSON to CSV
import json
import csv
with open('users.json') as f:
data = json.load(f)
# Flatten to list if nested under a key
if isinstance(data, dict):
data = data.get('users', list(data.values())[0])
with open('users.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
# jq + miller
jq -r '.[] | [.id, .name, .email, .age] | @csv' users.json > users.csv
# mlr (Miller)
mlr --ijson --ocsv cat users.json > users.csv
JSON to YAML
import json, yaml
with open('data.json') as f:
data = json.load(f)
with open('data.yaml', 'w') as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
# yq (YAML processor)
yq -P '.' data.json > data.yaml
JSON to XML
import json, xmltodict
with open('data.json') as f:
data = json.load(f)
xml_str = xmltodict.unparse({'root': data}, pretty=True)
with open('data.xml', 'w') as f:
f.write(xml_str)
JSON to Parquet (for analytics)
import pandas as pd
df = pd.read_json('data.json')
df.to_parquet('data.parquet', index=False, compression='snappy')
Parsing in Multiple Languages
# Python
import json
data = json.loads('{"name": "Alice", "age": 30}')
json_str = json.dumps(data, indent=2, ensure_ascii=False)
// JavaScript
const data = JSON.parse('{"name":"Alice","age":30}');
const jsonStr = JSON.stringify(data, null, 2);
# jq (shell)
echo '{"name":"Alice"}' | jq '.name'
# Output: "Alice"
// Go
import "encoding/json"
var data map[string]interface{}
json.Unmarshal([]byte(`{"name":"Alice"}`), &data)
JSON vs XML vs YAML
| Feature | JSON | XML | YAML |
|---|---|---|---|
| Human-readability | Good | Poor (verbose) | Excellent |
| Comments | No | Yes | Yes |
| Data types | 6 types | Strings only (schema-extended) | Rich (dates, binary, etc.) |
| Schemas | JSON Schema | XSD, DTD | (none standard) |
| Streaming | NDJSON | SAX parser | No standard |
| Namespaces | No | Yes | No |
| Attributes vs elements | N/A | Both | N/A |
| Size (same data) | Smallest | 30–50% larger | Similar to JSON |
| Language support | Universal | Universal | Universal |
| API standard | Near-universal | Legacy APIs | Config files |
| Best for | APIs, web data | Enterprise, document markup | Configuration |
JSON Performance Considerations
Parsing speed: JSON is fast — a modern JSON parser processes hundreds of MB/second. For very large files (>100MB), consider:
- Streaming parsers:
json.JSONDecoderwith raw_decode,ijson(Python),stream-json(Node.js) - Binary JSON alternatives: BSON (MongoDB), MessagePack, CBOR, Smile (Jackson)
- Columnar alternatives: Convert large JSON arrays to Parquet for analytical workloads
Schema validation at scale: Validate once on ingestion; don't re-validate on every read. Pre-compile schemas (AJV's ajv.compile(schema) creates a reusable validator function).
JSON's combination of simplicity, universality, and self-describing structure has made it the dominant data format for web APIs, configuration, and data exchange — a status that seems secure for the foreseeable future despite competition from binary formats in performance-critical contexts.
Related conversions
Document conversions that follow this topic naturally: