JSON Guide
The data format behind APIs, config files and databases β syntax, data types, objects and arrays, parsing and stringifying, validation, variants and the pitfalls that break your build. Every code block has a Copy button.
Copy button on each code block Β· β Beginner β Intermediate β Advanced01 Introduction β The Data Format of the Web
JSON (JavaScript Object Notation) is a lightweight, text-based format for representing structured data. It began as a subset of JavaScript syntax, but it is now language-independent and standardised as RFC 8259 and ECMA-404. Every mainstream language β Python, Go, Rust, Java, C#, PHP, Ruby β can read and write it out of the box.
Its job is simple: move data between programs. A server serialises an object to JSON text, ships it over HTTP, and the browser parses it back into a usable object. The same format also stores configuration, logs, telemetry, and entire databases.
Where you will meet JSON
- REST and GraphQL APIs β request bodies and responses
- Config files β
package.json,tsconfig.json,settings.json - Databases β MongoDB documents, PostgreSQL
jsonbcolumns - Logs and events β structured logging, analytics pipelines
- Integrations β webhooks, message queues, CI/CD metadata
- Browser storage β saved state in
localStorage
JSON is not JavaScript
A JavaScript object literal and a JSON document look similar, but JSON is stricter. Key differences:
- Keys must be double-quoted strings β
{ name: "Laksh" }is JavaScript, not JSON - No comments β
//and/* */are invalid - No trailing commas β the last item must not have one
- No functions,
undefined,NaNorInfinity - Strings use double quotes only β single quotes are invalid
null β but in practice it is almost always an object or an array at the top level.02 Syntax & Data Types Beginner
JSON has exactly six data types. Every value in every document is one of them.
A complete document
{
"name": "Laksh",
"age": 25,
"isDeveloper": true,
"nickname": null,
"skills": ["JavaScript", "Linux", "Git"],
"address": {
"city": "Mangalore",
"country": "India"
}
}
The rules in one place
- Keys are always strings wrapped in double quotes
- Colon separates a key from its value; commas separate pairs
- Whitespace is ignored β pretty-printing is purely cosmetic
- Values may be any of the six types, nested to any depth
- Duplicate keys are technically allowed, but the last one wins β avoid them
- No trailing comma after the final key/value pair or array item
Valid vs invalid β spot the difference
// β Invalid JSON
{
name: 'Laksh', // unquoted key, single quotes
"age": 25, // trailing comma
"active": true
}
// β
Valid JSON
{
"name": "Laksh",
"age": 25,
"active": true
}
03 Objects, Arrays & Nesting Beginner
Objects β unordered key/value pairs
An object maps names to values. The order of keys is not guaranteed by the spec β never rely on it when reading data.
{
"id": 101,
"title": "First post",
"published": true
}
Arrays β ordered lists
An array holds values in a definite order. Items can be of any type, including mixed types and nested arrays.
["apple", "banana", "cherry"]
[1, 2, 3, 4, 5]
[true, null, "mixed", { "nested": true }]
[[1, 2], [3, 4]]
The shape you will see most: an array of objects
APIs almost always return a list of records. This is the canonical JSON response shape.
{
"users": [
{ "id": 1, "name": "Ada", "role": "admin" },
{ "id": 2, "name": "Linus", "role": "developer" },
{ "id": 3, "name": "Grace", "role": "developer" }
],
"total": 3
}
Empty values
{
"object": {},
"array": [],
"string": "",
"number": 0,
"boolean": false,
"nothing": null
}
[] means βa list with zero itemsβ, while the key being absent means βno list was providedβ. APIs often distinguish the two β check before assuming.a.b.c.d.e and break when a field is missing.04 Strings, Numbers & Escapes Intermediate
Escape sequences
A few characters cannot appear literally inside a JSON string. Escape them with a backslash.
"quote: \"hello\""
"backslash: \\"
"newline: \n"
"tab: \t"
"carriage return: \r"
"unicode: \u00e9 (Γ©)"
"emoji: \ud83d\ude80 (π)"
\/ is legal but redundant β plain / needs no escaping. Escaping it is harmless, just unnecessary.Numbers have no type distinction
JSON does not separate integers from floats. Everything numeric is one number type, and the spec does not define a precision or range.
42
-3.14
1.5e10
0.0001
6.02214076e23
Invalid numbers include leading zeros (007), hexadecimal (0xFF), the special values NaN and Infinity, and a leading +.
2^53 - 1 (9007199254740991) cannot be represented exactly. Large database IDs and Snowflake IDs silently change when parsed. Send them as strings if precision matters.Dates are just strings
JSON has no date type. By convention, dates travel as ISO 8601 strings, and the consumer converts them.
{
"createdAt": "2026-10-19T09:30:00.000Z",
"updatedAt": "2026-10-19T12:00:00Z"
}
new Date(json.createdAt) to parse ISO strings in JavaScript. Prefer UTC (the trailing Z) to avoid timezone drift between server and client.05 JSON in JavaScript Intermediate
Every modern JavaScript runtime β browser, Node.js, Deno, Bun β provides exactly two methods through the global JSON object: parse and stringify.
Parsing β text to object
const text = '{"name":"Laksh","skills":["JS","Git"]}';
const user = JSON.parse(text);
console.log(user.name); // "Laksh"
console.log(user.skills[0]); // "JS"
Stringifying β object to text
const user = {
name: "Laksh",
skills: ["JS", "Git"],
active: true
};
JSON.stringify(user);
// '{"name":"Laksh","skills":["JS","Git"],"active":true}'
JSON.stringify(user, null, 2); // pretty-print with 2 spaces
Handling parse errors
Malformed input throws a SyntaxError. Always wrap parsing of external data.
function safeParse(text) {
try {
return { ok: true, value: JSON.parse(text) };
} catch (err) {
return { ok: false, error: err.message };
}
}
const result = safeParse('{ "broken": }');
// { ok: false, error: "Unexpected token } ..." }
Replacer and reviver
Both methods accept an optional hook. The replacer filters or transforms values while encoding; the reviver transforms values while decoding.
// Replacer: omit sensitive fields
JSON.stringify(user, (key, value) =>
key === "password" ? undefined : value
);
// Reviver: turn ISO strings into Date objects
const data = JSON.parse(text, (key, value) =>
key.endsWith("At") ? new Date(value) : value
);
What stringify silently drops
- Functions and
undefinedvalues are omitted from objects - Symbol-keyed properties are ignored
NaNandInfinitybecomenullDateobjects become ISO strings via theirtoJSON()- Circular references throw a
TypeError - Class instances lose their prototype β only own enumerable properties survive
JSON.parse(JSON.stringify(obj)) is a classic clone idiom, but it loses functions, class identity, undefined, Map/Set and dates (they become strings). For modern JavaScript, prefer structuredClone(obj).JSON.parse is safe on untrusted input β unlike eval, it only parses data and never executes code. Still validate the resulting shape before trusting it.06 JSON & HTTP APIs Intermediate
JSON is the default body format for web APIs. The two headers that matter are Content-Type (what you send) and Accept (what you want back).
Reading a JSON response
const res = await fetch("https://api.example.com/users");
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
const users = await res.json();
console.log(users[0].name);
Sending JSON in a request
const res = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
name: "Laksh",
role: "developer"
})
});
const created = await res.json();
Content-Type: application/json, many servers treat it as plain text and fail to parse the body. The header, not the string shape, is what tells the server how to read it.Checking before parsing
res.json() throws if the body is empty or is not JSON β common for 204 No Content and error responses that return HTML. Check status and content type first.
const type = res.headers.get("content-type") || "";
const data = type.includes("application/json")
? await res.json()
: await res.text();
Common status codes
fetch does not reject on 4xx or 5xx β it only rejects on network failure. Always check res.ok yourself, or use a client like Axios that throws for you.07 Validation & JSON Schema Advanced
A document can be syntactically valid JSON and still be wrong for your program. JSON Schema is the standard way to describe the expected shape and validate against it.
A small schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "name", "email"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"role": { "type": "string", "enum": ["admin", "developer", "viewer"] },
"tags": { "type": "array", "items": { "type": "string" } }
},
"additionalProperties": false
}
Common keywords
Validating in code
Ajv is the most widely used validator for JavaScript and Node.js. Similar libraries exist for every language.
import Ajv from "ajv";
const ajv = new Ajv();
const validate = ajv.compile(schema);
if (!validate(data)) {
console.error(validate.errors);
} else {
console.log("Valid!");
}
Quick checks without code
- VS Code validates
package.jsonandtsconfig.jsonautomatically using built-in schemas - jsonlint.com β paste a document to check syntax
jqβjq . file.jsonpretty-prints and fails loudly on invalid JSON- JSON Schema Store β community schemas for thousands of config formats
08 Variants & Related Formats Advanced
Strict JSON is deliberately minimal. Several extensions and sibling formats fill the gaps β just know which one a tool expects.
JSONL / NDJSON β one document per line
JSON Lines stores one complete JSON value per line. It is ideal for streaming, logs and big datasets because a consumer can process line by line without loading the whole file.
{"id":1,"event":"login","user":"ada"}
{"id":2,"event":"logout","user":"ada"}
{"id":3,"event":"login","user":"linus"}
JSON5 β JSON for humans
JSON5 allows comments, unquoted keys, single quotes, trailing commas and multi-line strings. It is popular in config files, but it is not standard JSON β APIs will reject it.
{
// comments are allowed
unquotedKey: 'single quotes',
trailing: true,
}
JSONC β JSON with Comments
VS Code's settings.json and TypeScript's tsconfig.json accept comments and trailing commas. The file is JSONC even though its extension says .json β a strict validator will complain.
How the formats compare
09 Pitfalls & Best Practices Intermediate
The classic mistakes
- Trailing commas β valid in JavaScript, fatal in JSON
- Comments β valid in JSONC/JSON5, fatal in strict JSON
- Unquoted or single-quoted keys β not JSON
- Smart quotes β copying from a word processor inserts
β β, which are not ASCII quotes - Hidden BOM characters β a byte-order mark at the start of a file breaks some parsers
- Encoding β JSON must be UTF-8; mismatched encodings produce mojibake
Security and correctness
- Never use
evalto parse JSON β useJSON.parse, which cannot execute code - Prototype pollution β a
"__proto__"or"constructor"key in untrusted JSON can poison object prototypes when merged blindly. Validate and strip unknown keys. - Big numbers β IDs above the safe integer limit must be strings
- Deep nesting β extremely deep documents can exhaust the call stack in recursive parsers; validate shape and depth on the server
- Huge payloads β set size limits and stream large data instead of loading it all at once
- Duplicate keys β behaviour is implementation-defined; the last value usually wins, which can mask bugs
Best practices
- Use camelCase keys consistently, matching the target language's conventions
- Send dates as ISO 8601 UTC strings, never as local timestamps
- Prefer
nullfor intentional absence and omit fields that are not applicable - Version your API payloads if the shape may evolve
- Pretty-print files that humans edit, minify payloads that machines transfer
- Validate with a schema at every boundary β client, server and database
- Wrap parsing in try/catch and surface a useful error
jq . or a JSON validator β it will point at the exact character, which is often a stray comma just before a closing brace.10 Cheat Sheet
Valid JSON in ten seconds
- Double quotes around every key and string
- No comments, no trailing commas, no single quotes
- Only six value types β no
undefined, functions,NaNorInfinity - Top level is usually an object or array
- Dates are ISO strings; big IDs are strings
- Parse with
JSON.parse, nevereval