Skip to main content

Working with JSON: stringify and parse

JSON.stringify() converts JavaScript data into a JSON string, and JSON.parse() converts a JSON string back into JavaScript data. This is one of the most frequently used pairs of methods in the language: it is needed everywhere data has to be stored or sent over the network.

Theory

TL;DR

  • JSON.stringify(value) is serialisation: an object or array becomes a string.
  • JSON.parse(text) is deserialisation: a string becomes an object or array.
  • stringify skips functions, undefined and Symbol, and walks nested objects recursively.
  • The third argument of stringify sets the indentation: JSON.stringify(obj, null, 2).
  • parse throws a SyntaxError on any invalid string, so it is usually wrapped in try/catch.
  • JSON.parse(JSON.stringify(obj)) is the popular trick for deep copying plain structures.

Quick example

javascript
const user = { name: 'Maria' }; const json = JSON.stringify(user); // '{"name":"Maria"}' const obj = JSON.parse(json); // { name: 'Maria' }

As a reminder, JSON is a text format for exchanging data, similar to JavaScript objects but meant for storage and transfer.

javascript
{ "name": "Maria", "age": 25, "isAdmin": false }

JSON.stringify(): object to string

The method converts a JavaScript object into a JSON formatted string.

javascript
const user = { name: 'Maria', age: 25, isAdmin: false }; const json = JSON.stringify(user); console.log(json); // '{"name":"Maria","age":25,"isAdmin":false}' console.log(typeof json); // "string"

Now json is an ordinary string that can be sent over the network or written to a file.

What JSON.stringify() actually does:

  • turns an object or an array into a string;
  • ignores functions, undefined and symbols (Symbol);
  • walks nested objects recursively.

An example with a function and undefined:

javascript
const data = { name: 'JS', greet() { console.log('Hi'); }, test: undefined }; console.log(JSON.stringify(data)); // '{"name":"JS"}', functions and undefined do not make it into JSON

Inside an array such values do not disappear, they are replaced with null: JSON.stringify([1, undefined, () => {}]) gives '[1,null,null]'.

Formatting and the replacer

The result can be formatted nicely with indentation:

javascript
const json = JSON.stringify(user, null, 2); console.log(json); /* { "name": "Maria", "age": 25, "isAdmin": false } */

The second argument is the replacer, the third one is the number of spaces used for formatting. As a replacer you can pass an array of keys to keep, or a function that processes every key-value pair:

javascript
JSON.stringify(user, ['name']); // '{"name":"Maria"}' JSON.stringify(user, (key, value) => key === 'age' ? undefined : value); // the age field is skipped

If an object has a toJSON() method, stringify calls it instead. That is why a Date is serialised into an ISO string.

JSON.parse(): string to object

The method converts a JSON string back into a JavaScript object.

javascript
const json = '{"name":"Maria","age":25,"isAdmin":false}'; const user = JSON.parse(json); console.log(user.name); // "Maria" console.log(user.age); // 25 console.log(typeof user); // "object"

If the string is not valid, you get an error:

javascript
JSON.parse("{name:'Maria'}"); // SyntaxError: Unexpected token n

The correct version:

javascript
JSON.parse('{"name":"Maria"}');

In JSON, keys and strings must always be in double quotes " ". Because of that, any JSON.parse() call on network data is worth wrapping in try/catch.

JSON.parse() has a second argument too, the reviver: a function that transforms every value while parsing, for example returning a Date instead of a string.

The two of them together

The methods are often used as a pair to persist data:

javascript
const user = { name: 'Maria', skills: ['JS', 'React'] }; const json = JSON.stringify(user); localStorage.setItem('user', json); // the string is saved const fromStorage = JSON.parse(localStorage.getItem('user')); console.log(fromStorage.skills); // ['JS', 'React']

This works precisely because localStorage can only store strings.

Deep copying an object

javascript
const obj = { a: 1, b: { c: 2 } }; const copy = JSON.parse(JSON.stringify(obj)); copy.b.c = 999; console.log(obj.b.c); // 2, the original did not change

This trick is often used to make a deep copy with no shared references. It only works for plain data; for everything else there is the built-in structuredClone(obj).

Summary table

MethodDirectionWhat it doesResult
JSON.stringify()object to stringturns a JS object into JSON text'{"name":"Maria"}'
JSON.parse()string to objectturns JSON text into a JS object{ name: 'Maria' }

Common mistakes

  • Calling JSON.parse() without try/catch. An empty server response or HTML instead of JSON takes the application down with an exception.
  • Expecting every field to survive serialisation. Functions, undefined and Symbol vanish from an object and become null inside an array.
  • Using JSON.parse(JSON.stringify(...)) on complex structures. A Date becomes a string, Map, Set and RegExp turn into empty objects, and BigInt throws a TypeError.
  • Forgetting circular references. An object that points at itself gives TypeError: Converting circular structure to JSON.
  • Hand-writing JSON with single quotes or a trailing comma. Such a string is valid JavaScript but invalid JSON.
  • Assuming JSON.stringify() guarantees a schema key order. The order comes from the object, so comparing two objects by comparing their JSON strings is unreliable.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.