JSON

JSON — JavaScript Object Notation — is a text format for exchanging data. Almost every web API sends and receives it, configuration files are written in it, and browsers store data with it. JavaScript converts between JSON text and real values with two functions: JSON.stringify and JSON.parse.

JSON is text

JSON looks like a JavaScript object literal, but it's a string with stricter rules:

JSON user.json
{
  "id": 42,
  "name": "Ana",
  "active": true,
  "roles": ["editor", "admin"],
  "manager": null,
  "address": { "city": "Lisbon" }
}
  • Keys must be in double quotes. Strings must use double quotes too.
  • Allowed values: strings, numbers, true/false, null, arrays and objects.
  • No functions, undefined, dates, comments or trailing commas.

JSON.stringify: value → text

JS stringify.js
const user = { id: 42, name: "Ana", roles: ["editor"], active: true };

const text = JSON.stringify(user);
console.log(text);
console.log(typeof text);
Output
{"id":42,"name":"Ana","roles":["editor"],"active":true}
string

Pass a third argument to pretty-print with indentation — great for debugging and config files:

JS pretty.js
console.log(JSON.stringify({ name: "Ana", tags: ["a", "b"] }, null, 2));
Output
{
  "name": "Ana",
  "tags": [
    "a",
    "b"
  ]
}

What stringify drops or changes

JS lossy.js
const data = {
  title: "Report",
  created: new Date(Date.UTC(2026, 0, 15)),
  notes: undefined,
  render() {},
  score: NaN,
  big: Infinity,
};

console.log(JSON.stringify(data));
Output
{"title":"Report","created":"2026-01-15T00:00:00.000Z","score":null,"big":null}

Functions and undefined properties disappear, NaN and Infinity become null, and dates become ISO strings. Maps, Sets and class instances lose their special behaviour. Keep data you serialise to plain objects, arrays and primitives.

JSON.parse: text → value

JS parse.js
const text = '{"product":"Lamp","price":30,"tags":["home","light"]}';
const product = JSON.parse(text);

console.log(product.price * 2);
console.log(product.tags[1]);
Output
60
light

Handling invalid JSON

JSON.parse throws a SyntaxError if the text isn't valid JSON — always wrap it in try/catch when the text comes from outside your program:

JS invalid.js
function safeParse(text, fallback = null) {
  try {
    return JSON.parse(text);
  } catch {
    return fallback;
  }
}

console.log(safeParse('{"ok": true}'));
console.log(safeParse("{ok: true}"));
console.log(safeParse("", []));
Output
{ ok: true }
null
[]

The second example fails because the key isn't quoted — valid JavaScript, invalid JSON.

Reviver and replacer functions

Both functions accept an optional callback that runs for every key–value pair. A reviver in parse can turn date strings back into Date objects:

JS reviver.js
const json = '{"event":"Launch","at":"2026-11-01T09:00:00.000Z"}';

const parsed = JSON.parse(json, (key, value) =>
  key === "at" ? new Date(value) : value
);

console.log(parsed.at instanceof Date, parsed.at.getUTCFullYear());
Output
true 2026

A replacer in stringify can filter or transform values — for example, passing an array of keys keeps only those properties:

JS replacer.js
const user = { id: 1, name: "Ana", passwordHash: "x9f…" };
console.log(JSON.stringify(user, ["id", "name"]));
Output
{"id":1,"name":"Ana"}

Custom serialisation with toJSON

JS tojson.js
class Money {
  constructor(cents) { this.cents = cents; }
  toJSON() { return (this.cents / 100).toFixed(2); }
}

console.log(JSON.stringify({ total: new Money(1999) }));
Output
{"total":"19.99"}

Common uses

  • APIs — fetch responses are usually JSON; await response.json() parses them (lesson 49).
  • Storage — localStorage only stores strings, so objects are stringified on save and parsed on load (lesson 48).
  • Configuration — package.json, tsconfig.json and many other config files.

Try it yourself

Try it yourself
Console output