JavaScript • Input and Output

JSON.parse & JSON.stringify — Parse JSON strings with JSON.parse and serialize with JSON.stringify

Learn how JavaScript converts data between objects and text strings so programs can store and share information.

JavaScript emblem with code brackets, braces, and a code file.
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

In the early days of the web, programs needed a way to send structured data between a web browser and a server. Before JSON (JavaScript Object Notation) existed, developers relied heavily on XML, a verbose markup language that required many lines of tags just to describe simple data. XML worked, but it was bulky and hard to read. Developers wanted something lighter — a format that was easy for both humans and machines to understand.

Douglas Crockford recognized that JavaScript's object literal syntax was already a clean, minimal way to represent data. He formalized this syntax into a standalone data format and named it JSON. Because JSON looks almost identical to the code developers were already writing in JavaScript, adoption was rapid. Today, JSON is the dominant data format for web APIs, configuration files, and data storage across virtually every programming language.

2001 • JSON Is Born

Douglas Crockford begins promoting JSON as a lightweight alternative to XML for data interchange on the web.

2005 • AJAX Revolution

The rise of AJAX (Asynchronous JavaScript and XML) popularizes sending data in the background. Despite the name, many developers switch from XML to JSON for its simplicity.

2009 • Native Browser Support

ECMAScript 5 introduces the built-in JSON object with JSON.parse() and JSON.stringify(), eliminating the need for external libraries.

2013 • ECMA-404 Standard

JSON receives its own ECMA standard (ECMA-404), solidifying it as a language-independent data format used across Python, Java, C#, and more.

The core challenge that JSON.parse and JSON.stringify solve is this: how do you convert a living JavaScript object into a plain text string that can be stored or transmitted, and how do you convert that string back into a usable object? This two-way conversion — called serialization and deserialization — is fundamental to almost every web application you use.

SECTION 2

Core Principles & Definitions

Before diving into the code, you need to understand a few foundational ideas. JSON is built on two universal data structures that exist in virtually every programming language: ordered lists (arrays) and key-value pairs (objects). These two building blocks can represent almost any kind of structured information, from a student's grade report to a social media post.

1

Serialization

The process of converting an in-memory JavaScript object into a JSON-formatted string. This is what JSON.stringify() does. Think of it as packing a suitcase — you organize your items into a flat, portable format.
2

Deserialization (Parsing)

The process of converting a JSON-formatted string back into a JavaScript object. This is what JSON.parse() does. Think of it as unpacking that suitcase and putting everything back where it belongs.
3

JSON Syntax Rules

Keys must be double-quoted strings. Values can be strings, numbers, booleans, null, arrays, or objects. No trailing commas, no single quotes, and no comments are allowed.
4

Data Types Supported

JSON supports six value types: strings, numbers, booleans (true/false), null, arrays, and objects. Functions, undefined, and Symbols are NOT valid JSON values and will be lost during serialization.
✦

KEY TAKEAWAY

Think of JSON as the "universal language" that programs speak when they need to share data. It's like writing a letter — you convert your thoughts (a JavaScript object) into words on paper (a JSON string) so someone else can read and understand them. JSON.stringify() writes the letter, and JSON.parse() reads it.

SECTION 3

Visual Explanation

The diagram below shows the two-way conversion between a JavaScript object and a JSON string. Notice how the object on the left is a live, in-memory data structure that your code can manipulate directly, while the string on the right is just plain text — a sequence of characters that could be saved to a file or sent across the internet.

JavaScript Object{name: "Alice",age: 16,courses: ["Math", "CS"]active: true}Live data in memoryJSON String'{"name": "Alice","age": 16,"courses": ["Math","CS"],"active": true}'Plain text (portable)JSON.stringify()JSON.parse()stringify() and parse() are inverse operations — they undo each otherJSON.parse(JSON.stringify(obj)) returns a deep copy of obj
The left box shows a JavaScript object with properties like name, age, and courses. The right box shows the same data as a JSON string. The cyan arrow represents JSON.stringify() converting the object to text, and the violet arrow represents JSON.parse() converting the text back to an object.

Notice a few key differences between the object and the JSON string. In the JavaScript object, property keys like name do not require quotes. In the JSON string, every key must be wrapped in double quotes. The entire JSON output is also wrapped in an outer pair of single quotes because it's a string value in JavaScript. This distinction — object versus string — is the entire reason these two methods exist.

SECTION 4

How JSON.parse & JSON.stringify Work

JSON.stringify() — Object to String

The JSON.stringify() method accepts up to three arguments. The first argument is the value you want to serialize. The optional second argument is a replacer — either an array of key names to include, or a function that transforms values during serialization. The optional third argument is a spacer — a number or string that adds indentation for readability.

STRINGIFY SYNTAX

JSON.stringify(value,replacer?,space?)JSON.stringify(value, replacer?, space?)

value = the object or array to convert; replacer = optional filter (array or function); space = optional indentation (number of spaces or string)

💡

Pretty-Printing Tip

Pass 2 as the third argument to get nicely indented output: JSON.stringify(obj, null, 2). This makes JSON much easier to read when debugging.

JSON.parse() — String to Object

The JSON.parse() method takes a JSON-formatted string and converts it back into a JavaScript value. It accepts two arguments. The first is the JSON string to parse. The optional second argument is a reviver function that lets you transform values as they are being parsed — for example, converting date strings back into Date objects.

PARSE SYNTAX

JSON.parse(text,reviver?)JSON.parse(text, reviver?)

text = a valid JSON string; reviver = optional function(key, value) that transforms each parsed value

⚠

Watch Out for Errors

If you pass an invalid JSON string to JSON.parse(), it throws a SyntaxError. Common mistakes include using single quotes instead of double quotes, forgetting to quote keys, or including trailing commas. Always wrap parse calls in a try...catch block when handling external data.

What Gets Lost in Translation

Not everything survives the round trip through stringify and parse. Functions, undefined values, and Symbols are silently dropped during serialization. Date objects are converted to strings but are NOT automatically converted back to Dates when parsed. NaN and Infinity become null. Understanding these limitations is essential to avoiding subtle bugs in your code.

SECTION 5

JSON Data Types & Edge Cases

Understanding exactly which data types are preserved, transformed, or lost during serialization is one of the most important things to master. The table below provides a complete reference for every common JavaScript type and what happens when you run it through JSON.stringify() and then JSON.parse().

JavaScript TypeAfter stringify()After parse()Preserved?
stringQuoted stringString✅ Yes
numberNumber literalNumber✅ Yes
booleantrue or falseBoolean✅ Yes
nullnullnull✅ Yes
ArrayJSON arrayArray✅ Yes
ObjectJSON objectPlain Object✅ Yes
DateISO stringString (not Date!)⚠️ Changed
undefinedOmitted / dropped—❌ Lost
FunctionOmitted / dropped—❌ Lost
NaN / Infinitynullnull⚠️ Changed

Behavior of JavaScript types during JSON serialization and deserialization

JSON.stringify() — What Happens to Each Type✅ PreservedstringnumberbooleannullArray / Object⚠️ ChangedDate → stringNaN → nullInfinity → null❌ DroppedundefinedFunctionSymbolCode Exampleconst data = {name: "Bob", // ✅ keptgreet: function() {}, // ❌ droppedcreated: new Date(), // ⚠️ becomes stringscore: undefined // ❌ dropped};
This diagram categorizes JavaScript types into three groups: types that survive serialization intact (green), types that get transformed into a different type (yellow), and types that are completely removed (red). The code example at the bottom shows a real object with mixed types and what happens to each property.

SECTION 6

Worked Example

Let's walk through a realistic scenario. Imagine you're building a student grade tracker, and you need to save a student's data to localStorage (the browser's built-in storage). Since localStorage can only store strings, you must serialize your object before saving it and parse it when loading it back.

Saving and Loading a Student Object with localStorage

  1. 1

    Step 1 — Create the JavaScript Object

    Start by defining a student object with various properties: const student = { name: "Maya", grade: 11, gpa: 3.8, honors: true, courses: ["AP CS", "Calculus", "English"] }; This object exists in memory and can be used in your code.
    Object with 5 properties including a string, number, boolean, and array.
  2. 2

    Step 2 — Serialize with JSON.stringify()

    Convert the object to a JSON string: const jsonString = JSON.stringify(student); The result is: '{"name":"Maya","grade":11,"gpa":3.8,"honors":true,"courses":["AP CS","Calculus","English"]}'. Notice how all keys are now double-quoted, and the entire result is a single string.
    A compact JSON string — all on one line, no extra whitespace.
  3. 3

    Step 3 — Store in localStorage

    Save the string using: localStorage.setItem("studentData", jsonString); The browser stores this string persistently. Even if the user closes the tab and comes back later, the data will still be there.
    Data is now safely stored as a string in the browser.
  4. 4

    Step 4 — Retrieve and Parse

    Later, retrieve the string and parse it: const retrieved = localStorage.getItem("studentData"); followed by const studentObj = JSON.parse(retrieved);. Now studentObj is a full JavaScript object again, and you can access properties like studentObj.name or studentObj.courses[0].
    studentObj.name → "Maya", studentObj.gpa → 3.8, studentObj.courses[0] → "AP CS"
  5. 5

    Step 5 — Verify the Round Trip

    You can verify that the data survived the round trip by checking: console.log(studentObj.honors); // true and console.log(typeof studentObj.gpa); // "number". All supported data types are correctly restored to their original types.
    All values preserved: strings, numbers, booleans, and arrays came through intact.

SECTION 7

JSON vs. Other Data Formats

JSON is not the only data format used in programming. Understanding how it compares to alternatives helps you appreciate why it has become the default choice for most web development. Below is a comparison of JSON with two other common formats: XML and CSV.

FeatureJSONXMLCSV
ReadabilityEasy to read and writeVerbose, lots of tagsVery simple but flat
Nested Data✅ Full support✅ Full support❌ No nesting
File SizeCompactLarge (extra tags)Smallest
JS IntegrationNative (parse/stringify)Requires DOM parserRequires custom parser
Data Types6 types supportedEverything is a stringEverything is a string
Comments❌ Not allowed✅ Supported❌ Not standard
Best ForAPIs, configs, storageDocuments, SOAP APIsSpreadsheets, tabular data

Comparison of JSON, XML, and CSV data formats

🏆

WHY JSON WINS FOR WEB DEVELOPMENT

JSON strikes the perfect balance between readability and power. Think of it like choosing between a suitcase, a shipping container, and an envelope. CSV is the envelope — light and simple, but you can only fit flat things. XML is the shipping container — it can hold anything, but it's heavy and complex. JSON is the suitcase — structured enough for complex data, but compact enough to carry easily. Since JavaScript can natively pack and unpack JSON suitcases with stringify() and parse(), it's the obvious choice for web apps.

SECTION 8

Connection to Advanced Techniques

Once you're comfortable with the basics of JSON.parse() and JSON.stringify(), several advanced patterns build on these fundamentals. The replacer, reviver, and deep-copy techniques are especially useful as your programs grow more complex.

Basic TechniqueAdvanced TechniqueWhen You'd Use It
JSON.stringify(obj)JSON.stringify(obj, replacer)Filter out sensitive fields like passwords before sending data
JSON.parse(str)JSON.parse(str, reviver)Convert date strings back into Date objects automatically
Shallow copy with spreadJSON.parse(JSON.stringify(obj))Create a deep copy where nested objects are independent clones
Manual formattingJSON.stringify(obj, null, 2)Pretty-print JSON for debugging or logging
Simple fetch requestsfetch() with JSON bodySend and receive JSON data from REST APIs

How basic JSON skills connect to advanced programming patterns

As you move into more advanced JavaScript — especially when working with frameworks like React or back-end tools like Node.js — you'll use JSON constantly. Every time your app communicates with a server via a REST API, the data travels as JSON text. The fetch() function's .json() method is essentially a wrapper around JSON.parse(). Modern JavaScript also offers structuredClone() as a more robust alternative to the JSON deep-copy trick, but understanding the JSON approach is still essential foundational knowledge.

ℹ

Looking Ahead

In your future coursework, you'll encounter the fetch() API, which relies heavily on JSON. A typical pattern looks like: fetch(url).then(res => res.json()).then(data => console.log(data)). The res.json() call parses the response body — it's JSON.parse under the hood.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain in your own words why you can't just store a JavaScript object directly in localStorage. What would happen if you tried localStorage.setItem("data", myObject) without using JSON.stringify()?
Show answer
The localStorage API can only store strings. If you pass an object directly, JavaScript will automatically call the object's .toString() method, which returns the useless string "[object Object]". All of your actual data — property names and values — would be completely lost. Using JSON.stringify() before storing ensures the object is converted into a meaningful, parseable string representation that preserves all supported data.

Question 2: BASIC CALCULATION

What will the following code output? const obj = { x: 10, y: 20 }; const str = JSON.stringify(obj); console.log(typeof str); console.log(str.length);
Show answer
The first console.log outputs "string" because JSON.stringify() always returns a string. The resulting string is {"x":10,"y":20}. Counting each character — the braces, quotes, colons, comma, and digits — gives us 15 characters. So the second log outputs 15. This exercise reinforces that the result of stringify is genuinely a string with a measurable length, not an object.

Question 3: INTERMEDIATE

Consider this code: const original = { name: "Zoe", greet: function() { return "Hi!"; }, score: undefined, gpa: 3.5 }; const copy = JSON.parse(JSON.stringify(original)); console.log(Object.keys(copy)); What keys will the copy object have, and why?
Show answer
The output will be ["name", "gpa"]. The greet property is dropped because functions are not valid JSON values — JSON.stringify() silently omits them. The score property is dropped because undefined is also not a valid JSON value. Only name (a string) and gpa (a number) survive the round trip because they are JSON-compatible types.

Question 4: APPLIED

You're building a to-do list app. Write a function called saveTodos(todos) that saves an array of to-do objects to localStorage under the key "todos", and a function called loadTodos() that retrieves and returns them. If there are no saved todos, loadTodos() should return an empty array. Include error handling for invalid JSON.
Show answer
Here is one valid solution: function saveTodos(todos) { localStorage.setItem("todos", JSON.stringify(todos)); } and function loadTodos() { try { const data = localStorage.getItem("todos"); return data ? JSON.parse(data) : []; } catch (e) { console.error("Invalid JSON in localStorage"); return []; } } The save function serializes the array to a string. The load function checks if data exists, parses it inside a try-catch block to handle potential corruption, and returns an empty array as a fallback. This pattern is used in virtually every web app that persists data locally.

Question 5: CRITICAL THINKING

A developer uses JSON.parse(JSON.stringify(obj)) to create a "deep copy" of an object. Explain what this technique does, why it works for simple objects, and identify at least two situations where this technique would produce incorrect or unexpected results. Suggest a modern alternative.
Show answer
This technique serializes the object to a JSON string and immediately parses it back, creating a completely new object with no shared references to the original. It works for objects containing only JSON-safe types (strings, numbers, booleans, null, plain objects, and arrays). However, it fails in at least two important ways. First, any Date objects become strings and are not converted back to Dates — typeof copy.date would be "string" instead of being a Date object. Second, any functions, undefined values, or Symbols are silently dropped, meaning the copy is missing properties that the original had. A modern alternative is structuredClone(obj), introduced in modern browsers, which handles Dates, Maps, Sets, and more correctly — though it still cannot clone functions.

SUMMARY

Lesson Summary

Summary

In this lesson, you learned two essential JavaScript methods for working with data. JSON.stringify() performs serialization — converting a JavaScript object or array into a JSON-formatted string that can be stored in localStorage, saved to a file, or sent across a network. JSON.parse() performs deserialization — converting a JSON string back into a usable JavaScript object. These two methods are inverse operations: one packs data for transport, the other unpacks it for use.

Remember that JSON supports six value types: strings, numbers, booleans, null, arrays, and objects. Types like functions, undefined, and Symbols are lost during the round trip, and Dates become strings. Always use a try...catch block when parsing external data to handle malformed JSON gracefully. With these tools in your toolkit, you're ready to build web apps that save, load, and communicate data like a professional developer.

Varsity Tutors • JavaScript • JSON.parse & JSON.stringify