Skip to content
beginner

Work with JSON in JavaScript: Parse and Stringify Data

You log a value from an API or from localStorage, and it looks exactly like an object. You can see the keys. You can see the values. So you try to read a…

Published 2026-10-03Updated 2026-10-0410 min read
Stunning sunset with a crescent moon, rich orange and red hues create a dramatic sky view.
Stunning sunset with a crescent moon, rich orange and red hues create a dramatic sky view. Photo by Oleksiy Yeshtokyn,🌻🇺🇦🌻 on Pexels.

You log a value from an API or from localStorage, and it looks exactly like an object. You can see the keys. You can see the values. So you try to read a property off it, and you get undefined.

That moment is where most beginners get stuck, and the fix is not a new method. It is a better mental model. JSON is not an object. JSON is text that describes data. JavaScript cannot touch that data until you convert it, and that conversion is the whole job of JSON.parse and JSON.stringify.

Two directions, one pair of methods: parse in, stringify out. Let's make that concrete.

JSON Is Text, Not an Object

JSON stands for JavaScript Object Notation. The syntax was inspired by JavaScript object literals, which is exactly why it fools you. It looks like code. It is not code. It is a string.

Here is the smallest experiment that proves it. Run this in your browser console or a Node script:

const jsonText = '{"name": "Ada", "age": 36}';
const realObject = { name: "Ada", age: 36 };

console.log(typeof jsonText);
console.log(typeof realObject);
console.log(jsonText.name);
console.log(realObject.name);
string
object
undefined
Ada

Look at the third line. jsonText.name gives undefined because you are indexing into a string, not reading a property from an object. Strings do not have a name property, so JavaScript hands you undefined instead of an error. That silent undefined is the symptom that sends beginners hunting for a bug in the wrong place.

Why does JSON exist at all if JavaScript already has objects? Because objects live in memory, and memory does not travel. You cannot email an object, store it in a text file, or send it over HTTP. JSON is a data interchange format — a shared text shape that a JavaScript client, a Python server, and a config file can all agree on. You already know how to build objects and arrays. JSON is how those structures leave your program and come back.

Note: JSON is language-independent. It was inspired by JavaScript, but it is not owned by JavaScript. That is why almost every language ships a JSON library.

Parse JSON Text into Usable Data

A JavaScript object flows through JSON.stringify into JSON text; JSON.parse sends that text back into a separate JavaScript value.
Use the direction of conversion to decide which method to call: stringify data going out, parse JSON text coming in.

JSON.parse(text) takes a JSON string and returns the JavaScript value it describes. That value can be an object, an array, a string, a number, a boolean, or null.

const jsonText = '{"user": {"name": "Ada", "roles": ["admin", "editor"]}}';

console.log(typeof jsonText);

const data = JSON.parse(jsonText);

console.log(typeof data);
console.log(data.user.name);
console.log(data.user.roles[1]);
string
object
Ada
editor

Notice the type change: string in, object out. After parsing, data behaves like any object literal you wrote yourself. There is no wrapper, no special API, no .get() call. You use dot syntax and bracket syntax exactly as you already do.

Arrays are valid JSON too, and parsing works the same way:

const scores = JSON.parse('[10, 20, 30]');
console.log(Array.isArray(scores));
console.log(scores[0] + scores[2]);
true
40

The rule to carry forward: parse once, then work with the result like normal JavaScript. If you find yourself calling JSON.parse on the same value repeatedly, you probably parsed too early or stored the wrong thing.

Knowledge check

Check your understanding

Answer this question before you continue.

What does this code print?
Output Prediction

Focus: Predict the JavaScript type returned when JSON.parse converts valid JSON text containing a string.

const value = JSON.parse('"ready"');
console.log(typeof value);

Stringify JavaScript Values Back into JSON

JSON.stringify(value) does the reverse. It takes a JavaScript value and returns a JSON string.

const user = { name: "Ada", age: 36, active: true };

const jsonText = JSON.stringify(user);

console.log(typeof jsonText);
console.log(jsonText);
string
{"name":"Ada","age":36,"active":true}

Two things to notice. First, typeof returns "string" — beginners often expect an object back and get confused when they try to read a property off the result. Second, the keys are now wrapped in double quotes. That is not decoration; it is the JSON format.

The round trip is what makes the pair memorable. Build an object, stringify it, parse it back, and confirm the values survived:

const original = { name: "Ada", age: 36 };
const text = JSON.stringify(original);
const restored = JSON.parse(text);

console.log(restored.name);
console.log(restored.age);
console.log(original === restored);
Ada
36
false

That last line matters. restored is a fresh copy, not the original object. The values match, but the reference does not. Any change you make to restored will not appear in original.

Knowledge check

Check your understanding

Answer this question before you continue.

Which string does this code produce?
Output Prediction

Focus: Predict how JSON.stringify handles an undefined object property.

const text = JSON.stringify({ name: "Ada", note: undefined });
console.log(text);

What JSON Can and Cannot Represent

JSON has a small vocabulary: objects, arrays, strings, numbers, booleans, and null. That is the entire list. Anything outside it gets reshaped or dropped during JSON.stringify, and the reshaping is silent.

JavaScript valueWhat appears in the JSON outputWhy it matters
undefined (as a property)The property is removedYou lose the key entirely
undefined (inside an array)nullArray positions are preserved, values are not
Function or methodSkippedMethods do not survive a round trip
NaN, InfinitynullNumeric edge cases become indistinguishable from "no value"
SymbolSkippedSymbol-keyed data disappears
DateAn ISO string like "2024-01-01T00:00:00.000Z"Comes back as a string, not a Date

Here is the failure in code:

const record = {
  id: 1,
  nickname: undefined,
  score: NaN,
  createdAt: new Date("2024-01-01T00:00:00Z"),
  greet() { return "hi"; }
};

const text = JSON.stringify(record);
console.log(text);

const back = JSON.parse(text);
console.log(typeof back.createdAt);
console.log(back.nickname);
{"id":1,"score":null,"createdAt":"2024-01-01T00:00:00.000Z"}
string
undefined

The nickname key is gone. score became null. greet vanished. And createdAt came back as a string, so calling back.createdAt.getFullYear() will throw.

Common mistake: Assuming a Date survives the round trip. It does not. If you need a real Date after parsing, rebuild it yourself: new Date(back.createdAt).

The decision rule is simple. If a value must survive a round trip, store it in a JSON-safe form — a string, number, boolean, array, plain object, or null — and rebuild the richer type after parsing.

Knowledge check

Check your understanding

Answer this question before you continue.

When JSON.stringify encounters undefined, what happens in these two cases?
Single Choice

Focus: Identify how JSON.stringify represents undefined in an object property versus an array position.

When Parsing Fails: Malformed JSON

JSON.parse does not return null on bad input. It throws a SyntaxError. If you are not ready for that, your script stops.

The most common causes are small syntax slips that JavaScript tolerates but JSON does not:

  • Single quotes instead of double quotes
  • A trailing comma after the last property
  • Unquoted keys
  • Comments (// or /* */)
  • Passing an object that is already parsed

Here is what the error looks like:

try {
  JSON.parse("{'name': 'Ada'}");
} catch (error) {
  console.log(error.name);
  console.log(error.message);
}
SyntaxError
Unexpected token '

Read the message. It usually names the character or position where parsing broke, which points straight at the offending spot. In this case, the single quote is the culprit — JSON requires double quotes.

When the input comes from outside your program — an API, a file, localStorage, a user paste — wrap the parse in try/catch and decide what the fallback should be:

function safeParse(text, fallback = null) {
  try {
    return JSON.parse(text);
  } catch (error) {
    console.log("Could not parse:", error.message);
    return fallback;
  }
}

console.log(safeParse('{"ok": true}'));
console.log(safeParse("not json"));
{ ok: true }
Could not parse: <engine-specific SyntaxError message>
null

The exact wording of error.message varies between JavaScript engines and versions, so do not treat the text above as a fixed string. What stays stable is the behavior: parsing throws, the catch runs, and your fallback is returned.

Tip: Log the raw string before parsing. If you only log the parsed result, you never see what the parser actually saw.

Knowledge check

Check your understanding

Answer this question before you continue.

Why does this call throw a SyntaxError?
Debugging

Focus: Recognize that JSON strings require double quotes and diagnose that syntax error in a parse call.

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

Common Beginner Mistakes to Avoid

These are the mistakes I see most often, and each one comes from mixing up text and objects.

Stringifying twice. The second call escapes the first result, so you get a string full of backslashes:

const person = { name: "Ada" };
const once = JSON.stringify(person);
const twice = JSON.stringify(once);

console.log(once);
console.log(twice);
{"name":"Ada"}
"{\"name\":\"Ada\"}"

If you see backslashes in your output, you almost certainly stringified something that was already a string.

Parsing something that is already an object. JSON.parse expects a string. Pass it an object and it throws, because it will try to coerce the object to a string first and then fail on the result.

Assuming a parsed value is a live reference. It is a copy. Changes do not travel back to the original.

Expecting methods and class instances to survive. JSON.stringify keeps plain data only. Prototypes, getters, and custom methods are not part of the format.

A quick habit that prevents all four: log typeof before and after every conversion until the pattern becomes automatic.

Where You Will Actually Use This

You will meet this pair constantly, and recognizing the pattern early saves a lot of confusion.

  • Reading an API response. When you read the response as text — for example with response.text() — you parse it before touching the data. Many browser helpers, such as response.json(), do that parse step for you and hand you a value directly.
  • Saving to localStorage. Storage only holds strings, so you stringify on the way in and parse on the way out.
  • Sending a POST request. The body must be a JSON string, so you stringify the object first.
  • Config files and fixtures. JSON is the format you will read most often when a project ships sample data.

Each of these is a full topic on its own. For now, the point is orientation: check what you are actually holding. If it is JSON text, parse it. If it is a JavaScript value, work with it directly. The conversion is driven by the value in hand, not by the fact that data moved.

Practice: Round-Trip a Small Object

Here is a deliberate drill that exercises both methods and forces you to observe the type changes.

Step 1. Create an object with a string, a number, a boolean, a nested object, and one undefined property.

const profile = {
  username: "ada",
  level: 7,
  verified: true,
  settings: { theme: "dark" },
  lastSeen: undefined
};

Step 2. Stringify it and log the result. Before you run it, predict which property disappears.

const text = JSON.stringify(profile);
console.log(text);
{"username":"ada","level":7,"verified":true,"settings":{"theme":"dark"}}

lastSeen is gone. If you predicted that, the mental model is working.

Step 3. Parse the string back and compare it to the original.

const restored = JSON.parse(text);
console.log(restored.settings.theme);
console.log("lastSeen" in restored);
dark
false

Step 4. Deliberately break the JSON string — remove a quote or add a trailing comma — and read the error message.

try {
  JSON.parse('{"username":"ada",}');
} catch (error) {
  console.log(error.name);
}
SyntaxError

The parser is telling you exactly where your mental model and the format disagreed. The message text will differ across engines, but the SyntaxError name will not.

Use typeof at every stage to confirm what you are holding. Text or object — the answer changes what you can do next.

What to Do Next

The decision rule is short enough to memorize: text coming in gets parsed, data going out gets stringified, and anything that crosses that boundary must be JSON-safe.

The best next step is to use this pair inside a real boundary. Try a fetch call where you read the response as text and parse it yourself, then compare that with a version that uses response.json() and skips the manual parse. Or save a small object to localStorage and read it back on the next page load. Both exercises force you to handle the conversion in a working context instead of a console snippet, and both will teach you why the parse step exists the moment you forget it.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

You see backslashes around escaped quotes after converting data to JSON. What is the likely cause?
Question 1 of 2Misconception Check

Focus: Explain why stringifying an already-stringified value produces escaped quotes and backslashes.

Which sequence matches the article's guidance for storing an object in localStorage and using it later?
Question 2 of 2Single Choice

Focus: Choose the conversion direction for saving a JavaScript value to localStorage and reading it back.

References

  1. Working with JSON - Learn web development | MDNdeveloper.mozilla.org
  2. JSON methods, toJSONjavascript.info
Practical resource

Want a more structured JavaScript path?

Use the JavaScript for AI Applications Starter Pack to turn individual tutorials into a focused path from language fundamentals to interactive AI applications.

View the bundle
Coming soon

JavaScript for AI Applications Starter Pack

Build the JavaScript foundation behind modern interactive applications. The JavaScript for AI Applications Starter Pack takes you from core language concepts through functions, browser events, forms, DOM updates, application state, debugging, and practical projects—so you can learn how interfaces take input, work with structured data, respond to users, and turn results into experiences people can actually use.

$9
PDF BundleJavaScriptWeb DevelopmentAI Applications
  • 253-page illustrated PDF
  • 12 guided JavaScript chapters
  • Visual concept diagrams
  • Self-assessment quizzes
  • Bonus deep-dive sections
  • DOM, events, forms & application state
  • Browser projects, debugging & practical workflows

Coming soon

Keep learning

Related tutorials

Continue with nearby JavaScript topics and beginner-friendly explanations.

A library shelf filled with colorful children's books, focused on educational topics.
beginner
9 min read

Arrays and Objects Basics

A variable can hold one value—and that value can be a collection holding many related values. JavaScript arrays and objects are how you build those…

Read tutorial