JSON is the format of nearly every web API, config file and local storage entry.
JSON is a text format based on JavaScript literals, but stricter: keys must be double-quoted strings, there are no comments or trailing commas, and the only values are strings, numbers, booleans, null, arrays and objects.
JSON.stringify(value) turns a value into JSON text; JSON.parse(text) turns text back into values. A third argument to stringify pretty-prints: JSON.stringify(data, null, 2).
Not everything survives the round trip:
undefined, functions and symbols are dropped from objects (and becomenullin arrays).Dateobjects become ISO strings (via theirtoJSONmethod) and come back as plain strings.Map,Setand class instances become plain{}or lose their prototype.NaNandInfinitybecomenull.BigIntthrows aTypeError.- Circular references throw.
You can customise both directions. Objects can define toJSON() to control their serialised form. The second argument of stringify (a replacer function or array of keys) filters or transforms properties, and the second argument of parse (a reviver) transforms values on the way in — for example turning date strings back into Dates.
JSON.parse throws a SyntaxError on invalid input, so wrap parsing of anything external — user input, files, localStorage — in try...catch.
A tempting trick, JSON.parse(JSON.stringify(obj)), makes a deep copy but silently loses dates, undefined and more. Use structuredClone(obj) instead.
Example
const event = {
title: "Launch",
date: new Date("2025-06-01T10:00:00Z"),
notes: undefined,
attendees: new Set(["ada"]),
};
const text = JSON.stringify(event);
console.log(text);
// {"title":"Launch","date":"2025-06-01T10:00:00.000Z","attendees":{}}
const revived = JSON.parse(text, (key, value) =>
key === "date" ? new Date(value) : value);
console.log(revived.date instanceof Date); // true
function safeParse(raw, fallback) {
try { return JSON.parse(raw); }
catch { return fallback; }
}
console.log(safeParse("{bad json}", {})); // {}
try { JSON.stringify({ id: 1n }); }
catch (e) { console.log(e.name); } // TypeError (BigInt)Remember
stringifydrops undefined/functions, turns Dates into strings and Maps/Sets into {}JSON.parsethrows on bad input — guard external data- Use a reviver or
toJSONto customise conversion;structuredClonefor deep copies
Watch out for
- Expecting dates to come back from
JSON.parseasDateobjects.