Loading
Understand JSON structure, parsing, serialization, API payloads, and common pitfalls that trip up beginners.
JSON (JavaScript Object Notation) is the standard format for sending data between a browser and a server, between microservices, between a config file and an application. If you work with web development, you will read and write JSON every single day. This guide covers everything you need to know.
JSON has six data types: strings, numbers, booleans, null, arrays, and objects.
Rules that trip people up:
"name" is valid. name and 'name' are not.[1, 2, 3,] but JSON does not.null instead."hello" is valid. 'hello' is not.0.5 is valid. 05 is not.Valid JSON must be a single value at the top level — usually an object {} or array []:
Parsing converts a JSON string into a JavaScript object. Serialization converts a JavaScript object into a JSON string.
JSON.parse throws an error if the string is not valid JSON. Always handle this:
JSON.stringify silently drops some values:
When you fetch data from an API, the response body is a JSON string. The fetch API has a built-in method to parse it:
When sending JSON to an API, you must set the Content-Type header and stringify the body:
A typical API response structure:
An error response:
Dates are not a JSON type. JSON has no date type, so dates are serialized as strings. You must parse them manually:
Using a reviver function to auto-convert dates during parsing:
Circular references break JSON.stringify:
Large numbers lose precision:
Deeply nested access is unsafe:
Duplicate keys are technically valid but unpredictable:
Most parsers use the last value ("Bob"), but the behavior is not guaranteed by the spec. Avoid duplicate keys.
JSON is simple by design — six types, strict syntax, no ambiguity. That simplicity is its greatest strength. Learn these rules once and you can read configuration files, API responses, database records, and message queues in any programming language.
// Parsing: string → object
const jsonString = '{"name": "Alice", "age": 28}';
const user = JSON.parse(jsonString);
console.log(user.name); // "Alice"
// Serialization: object → string
const data = { name: "Bob", skills: ["JS", "Python"] };
const output = JSON.stringify(data);
console.log(output); // '{"name":"Bob","skills":["JS","Python"]}'
// Pretty-print with 2-space indentation
const pretty = JSON.stringify(data, null, 2);
console.log(pretty);
// {
// "name": "Bob",
// "skills": [
// "JS",
// "Python"
// ]
// }function safeJsonParse<T>(text: string): T | null {
try {
return JSON.parse(text) as T;
} catch {
console.error("Failed to parse JSON:", text.slice(0, 100));
return null;
}
}
const result = safeJsonParse<User>(responseBody);
if (result) {
// use result safely
}const data = {
name: "Alice",
greet: function () {
return "hi";
}, // dropped — functions are not valid JSON
secret: undefined, // dropped — undefined is not valid JSON
count: NaN, // becomes null
big: Infinity, // becomes null
};
JSON.stringify(data);
// '{"name":"Alice","count":null,"big":null}'// Fetching JSON from an API
async function getUsers(): Promise<User[]> {
const response = await fetch("/api/users");
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data: User[] = await response.json();
return data;
}// Sending JSON to an API
async function createUser(user: CreateUserInput): Promise<User> {
const response = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(user),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}const json = '{"createdAt": "2024-03-15T10:30:00Z"}';
const obj = JSON.parse(json);
console.log(typeof obj.createdAt); // "string" — NOT a Date object
// Parse it yourself
const date = new Date(obj.createdAt);const parsed = JSON.parse(json, (key, value) => {
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
return new Date(value);
}
return value;
});const a: Record<string, unknown> = { name: "Alice" };
const b: Record<string, unknown> = { name: "Bob", friend: a };
a.friend = b; // circular reference
JSON.stringify(a); // TypeError: Converting circular structure to JSON// JavaScript numbers are 64-bit floats
// IDs larger than 2^53 lose precision
const json = '{"id": 9007199254740993}';
JSON.parse(json).id; // 9007199254740992 — wrong!
// Solution: use string IDs
const safe = '{"id": "9007199254740993"}';// This crashes if response, data, or users is missing
const name = response.data.users[0].name;
// Safe access with optional chaining
const name = response?.data?.users?.[0]?.name;{
"name": "Alice Chen",
"age": 28,
"isStudent": true,
"graduationDate": null,
"skills": ["TypeScript", "React", "SQL"],
"address": {
"city": "Portland",
"state": "OR"
}
}["one", "two", "three"]{
"status": "ok"
}{
"data": {
"id": "usr_abc123",
"name": "Alice Chen",
"email": "alice@example.com"
},
"meta": {
"requestId": "req_xyz789",
"timestamp": "2024-03-15T10:30:00Z"
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": [{ "field": "email", "rule": "required" }]
}
}{
"name": "Alice",
"name": "Bob"
}