JSON.parse() and JSON.stringify() Explained for Beginners

Hero image for JSON.parse() and JSON.stringify() Explained for Beginners. Image by Anjo Cerdeña.
Hero image for 'JSON.parse() and JSON.stringify() Explained for Beginners.' Image by Anjo Cerdeña.

JSON.parse() and JSON.stringify() show up everywhere in frontend JavaScript, but beginners often learn them as two magic lines rather than as tools for converting between two different kinds of thing.

That is why people end up writing code like JSON.parse(someObject) or storing an object directly in localStorage and then wondering why it comes back wrong later. The syntax is easy enough to memorise. The real job is understanding what problem the functions are solving.

The short version is this:

  • JSON.stringify() turns a JavaScript value into JSON text
  • JSON.parse() turns JSON text back into a JavaScript value

Once that distinction is clear, most of the common beginner mistakes become easier to avoid.


JSON is Text, Not a JavaScript Object

This is the part people need to get straight first.

JSON is a string format for representing data. It looks a lot like a JavaScript object literal, which is why people blur the two together, but it is still text.

For example, this is a JavaScript object:

const user = {  name: 'Maddie',  role: 'Editor',};

This is JSON text:

{"name":"Maddie","role":"Editor"}

They look similar, but they are not the same kind of value. One is an inmemory JavaScript object. The other is a string.

That difference is the whole reason parse and stringify exist.


What JSON.stringify() does

JSON.stringify() serialises a JavaScript value into a JSON string.

const user = {  name: 'Maddie',  role: 'Editor',};const json = JSON.stringify(user);console.log(json);

The result is:

{"name":"Maddie","role":"Editor"}

This is useful when you need to send data somewhere that expects text, or store structured data in an API that only keeps strings.

The most common browser example is localStorage.

const settings = {  theme: 'dark',  showTips: true,};localStorage.setItem('settings', JSON.stringify(settings));

If you skip JSON.stringify there, the storage layer does not magically preserve your object structure. It stores strings.


What JSON.parse() does

JSON.parse() goes in the opposite direction. It takes JSON text and turns it back into a JavaScript value.

const savedSettings = localStorage.getItem('settings');const settings = savedSettings ? JSON.parse(savedSettings) : null;

Now settings is a JavaScript object again, not a JSON string.

That is the full round trip:

  1. start with a JavaScript object
  2. turn it into JSON text with stringify
  3. store or transmit that text
  4. turn it back into a JavaScript value with parse

Once you see the two functions as opposite ends of the same conversion, they stop looking arbitrary.


The Most Common Beginner Mistake

The mistake I see most often is calling JSON.parse() on a value that is already an object.

const user = {  name: 'Maddie',};JSON.parse(user);

That fails because JSON.parse expects a string. It cannot parse an object value directly.

The matching mistake in the other direction is forgetting to parse something that is still a string.

const savedUser = localStorage.getItem('user');console.log(savedUser?.name);

That will not work because savedUser is a string or null, not an object with a name property.

Both mistakes come from the same misunderstanding: not keeping track of whether the current value is text or a JavaScript structure.


API Responses Create the Same Pattern

This is not only about storage. The same idea appears whenever data crosses a boundary.

Servers often send JSON as part of an HTTP response. At some point, that response body is converted from text into a JavaScript value so your code can work with it.

That is why JSON is so common on the web. It is a text format that moves easily between systems, but it maps neatly back into arrays, objects, numbers, booleans, strings, and null.

Even if a library handles the parsing step for you, it still helps to understand what is happening under the hood. Otherwise you can end up trying to parse values twice or assuming text is already structured data.


Not everything survives JSON.stringify()

This is where the function starts to feel less magical and more limited, which is a good thing to understand early.

JSON is good at plain data. It is not good at preserving every possible JavaScript value.

For example:

const example = {  title: 'Hello',  count: 3,  enabled: true,  missing: undefined,  run: () => {    console.log('Running');  },};console.log(JSON.stringify(example));

The resulting JSON will not include the function, and undefined values are dropped as well.

That surprises beginners because it feels like the whole object should be preserved exactly. It is not. JSON.stringify preserves JSONcompatible data, not arbitrary JavaScript behaviour.


Dates and Other Special Values Need Care

Dates are another common gotcha.

const article = {  publishedAt: new Date(),};const json = JSON.stringify(article);const parsed = JSON.parse(json);

After parsing, parsed.publishedAt is a string, not a Date object.

That is not a bug. JSON does not have a special date type. It only has text, numbers, booleans, arrays, objects, null, and the syntax needed to describe them.

So when data goes through JSON, richer JavaScript objects often come back as simpler representations unless you rebuild them deliberately.


Circular References Will Fail

Another useful limitation to know is that JSON.stringify cannot handle circular references.

type Node = {  name: string;  self?: Node;};const node: Node = {  name: 'root',};node.self = node;JSON.stringify(node);

That throws because the object refers back to itself. JSON is a treelike data format, and circular structures do not fit into it cleanly.

You do not need to become an expert in serialisation theory to use JSON day to day, but it helps to know that stringify is not a universal deepcloning spell.


JSON.parse() can throw too

JSON.parse() assumes the input text is valid JSON. If it is not, parsing fails.

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

That breaks because valid JSON requires doublequoted property names and string values. JavaScript object literal rules and JSON rules are close cousins, not identical twins.

That is another reason to be clear about what kind of data you are dealing with. A JavaScriptlooking string is not automatically valid JSON.


A Useful Way to Think About Both Functions

When beginners struggle with parse and stringify, the problem is usually that they are thinking in terms of syntax instead of boundaries.

Ask a better question:

  • am I moving from JavaScript data to text?
  • or from text back to JavaScript data?

If you are going out to storage or across the network, you often need stringify.

If you are coming back from storage or receiving JSON text, you often need parse.

That mental model is much more reliable than memorising random code fragments.


Wrapping up

JSON.stringify() and JSON.parse() are simple once you stop treating JSON as if it were the same thing as a JavaScript object. One function turns structured JavaScript data into text. The other turns valid JSON text back into structured data. The bugs happen when we lose track of which side of that boundary we are on.

Key Takeaways

  • JSON is a text format, not the same thing as a JavaScript object.
  • JSON.stringify() converts JavaScript values into JSON strings.
  • JSON.parse() converts JSON strings into JavaScript values.
  • Functions, undefined, dates, and circular references do not roundtrip cleanly through JSON.
  • Most mistakes come from forgetting whether the current value is text or structured data.

Once that distinction sticks, parse and stringify stop feeling like trivia and start feeling like ordinary, useful conversions.


Categories:

  1. Development
  2. Front‑End Development
  3. Guides
  4. JavaScript