JavaScript 12 min read

How to Parse JSON in JavaScript

Master JSON.parse() and JSON.stringify() with practical examples. Learn error handling, reviver functions, and advanced techniques for working with JSON in JS.

#javascript #parsing #code #tutorial

TL;DR

  • JSON.parse() — Convert JSON string to JavaScript object
  • JSON.stringify() — Convert JavaScript object to JSON string
  • Always wrap in try-catch — Invalid JSON throws errors
  • Use reviver/replacer functions for custom transformations
  • JSON.stringify(obj, null, 2) — Pretty print with indentation

The Two Methods You Need

JavaScript has exactly two built-in methods for working with JSON. That's it. Two methods. You'll use them constantly:

  • JSON.parse() — String → Object
  • JSON.stringify() — Object → String

These methods are global. They're always available. They're fast. They're your new best friends.

1. JSON String { "name" : "Alice" } Text/String format JSON.parse() 2. JS Object { name : "Alice" } Native JavaScript JSON.stringify() 3. JSON String { "name" : "Alice" } Back to string Key JavaScript Methods JSON.parse() JSON.stringify()
JSON parsing flow: String to Object and back using built-in JavaScript methods

JSON.parse() — String to Object

Got a JSON string? Need a JavaScript object? JSON.parse() is your answer.

parse-basic.js
javascript
// Simple parsing
const jsonString = '{"name": "Alice", "age": 25}';
const user = JSON.parse(jsonString);

console.log(user.name);  // "Alice"
console.log(user.age);   // 25
console.log(typeof user); // "object"

Parsing Arrays

Arrays work exactly the same way:

parse-array.js
javascript
const jsonArray = '[1, 2, 3, "four", true]';
const arr = JSON.parse(jsonArray);

console.log(arr);        // [1, 2, 3, "four", true]
console.log(arr[3]);     // "four"
console.log(Array.isArray(arr)); // true

Parsing Nested Data

Complex nested structures? No problem:

parse-nested.js
javascript
const json = `{
  "company": "TechCorp",
  "employees": [
    {"name": "Alice", "role": "Engineer"},
    {"name": "Bob", "role": "Designer"}
  ],
  "location": {
    "city": "San Francisco",
    "country": "USA"
  }
}`;

const data = JSON.parse(json);

console.log(data.company);           // "TechCorp"
console.log(data.employees[0].name); // "Alice"
console.log(data.location.city);     // "San Francisco"

Error Handling — Don't Skip This

Here's the thing: invalid JSON will throw an error. Not return null. Not return undefined. It will throw. Your code will crash if you don't handle it.

parse-error.js
javascript
// This will crash your app!
const badJson = '{name: "Alice"}';  // Missing quotes around key
const data = JSON.parse(badJson);   // 💥 SyntaxError!

Always wrap JSON.parse() in try-catch:

safe-parse.js
javascript
function safeJsonParse(jsonString) {
  try {
    return JSON.parse(jsonString);
  } catch (error) {
    console.error('Invalid JSON:', error.message);
    return null;
  }
}

// Safe to use
const data = safeJsonParse('{invalid}');
if (data) {
  // Work with data
} else {
  // Handle the error case
}
Pro tip: Never trust JSON from external sources. Always validate and wrap in try-catch. API responses, user input, file contents — assume it could be malformed.

The Reviver Function — Advanced Parsing

JSON.parse() takes an optional second argument: a reviver function. This function is called for every key-value pair, letting you transform values during parsing.

reviver.js
javascript
const json = '{"name": "Alice", "birthDate": "1995-06-15"}';

// Parse with a reviver to convert date strings
const user = JSON.parse(json, (key, value) => {
  // Check if the value looks like a date
  if (key === 'birthDate') {
    return new Date(value);
  }
  return value;
});

console.log(user.birthDate);           // Date object
console.log(user.birthDate.getFullYear()); // 1995

Common Reviver Use Cases

revivers.js
javascript
// 1. Convert all dates automatically
function dateReviver(key, value) {
  const datePattern = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/;
  if (typeof value === 'string' && datePattern.test(value)) {
    return new Date(value);
  }
  return value;
}

// 2. Convert string numbers to actual numbers
function numberReviver(key, value) {
  if (typeof value === 'string' && !isNaN(value) && value.trim() !== '') {
    return Number(value);
  }
  return value;
}

// 3. Convert keys to camelCase
function camelCaseReviver(key, value) {
  if (key === '') return value; // Root object
  // This transforms the key, not value
  return value;
}

JSON.stringify() — Object to String

Need to convert a JavaScript object to a JSON string? Maybe for sending to an API, storing in localStorage, or logging? JSON.stringify() has you covered.

stringify-basic.js
javascript
const user = {
  name: "Bob",
  age: 30,
  hobbies: ["coding", "gaming"]
};

const jsonString = JSON.stringify(user);
console.log(jsonString);
// '{"name":"Bob","age":30,"hobbies":["coding","gaming"]}'

Pretty Printing

By default, stringify produces minified JSON. For human-readable output, use the third parameter:

stringify-pretty.js
javascript
const user = {
  name: "Bob",
  age: 30,
  address: { city: "NYC", zip: "10001" }
};

// Minified (default)
JSON.stringify(user);
// '{"name":"Bob","age":30,"address":{"city":"NYC","zip":"10001"}}'

// Pretty printed with 2-space indentation
JSON.stringify(user, null, 2);
/*
{
  "name": "Bob",
  "age": 30,
  "address": {
    "city": "NYC",
    "zip": "10001"
  }
}
*/

// With tab indentation
JSON.stringify(user, null, '\t');

The Replacer Function — Control What's Stringified

The second parameter of stringify() can be a replacer function or array. This lets you filter or transform values during stringification.

Using an Array (Whitelist Keys)

replacer-array.js
javascript
const user = {
  name: "Alice",
  email: "alice@example.com",
  password: "secret123",  // Sensitive!
  role: "admin"
};

// Only include specific keys
const safeJson = JSON.stringify(user, ['name', 'email', 'role']);
console.log(safeJson);
// '{"name":"Alice","email":"alice@example.com","role":"admin"}'
// password is excluded!

Using a Function (Transform Values)

replacer-function.js
javascript
const user = {
  name: "Alice",
  password: "secret123",
  createdAt: new Date('2024-01-15')
};

const json = JSON.stringify(user, (key, value) => {
  // Hide sensitive data
  if (key === 'password') {
    return undefined;  // Exclude from output
  }
  
  // Convert dates to ISO strings
  if (value instanceof Date) {
    return value.toISOString();
  }
  
  return value;
}, 2);

console.log(json);
/*
{
  "name": "Alice",
  "createdAt": "2024-01-15T00:00:00.000Z"
}
*/

Edge Cases and Gotchas

What Gets Lost in Stringification

Not everything survives the round trip. Here's what JSON.stringify() drops:

what-gets-lost.js
javascript
const obj = {
  name: "Test",
  func: function() { return 42; },    // Functions - DROPPED
  undef: undefined,                    // undefined - DROPPED
  sym: Symbol('id'),                   // Symbols - DROPPED
  bigNum: BigInt(9007199254740991),   // BigInt - THROWS ERROR!
  nan: NaN,                            // Becomes null
  inf: Infinity,                       // Becomes null
  date: new Date()                     // Becomes string
};

console.log(JSON.stringify(obj, null, 2));
/*
{
  "name": "Test",
  "nan": null,
  "inf": null,
  "date": "2024-11-26T12:00:00.000Z"
}
*/
BigInt warning: JSON.stringify() throws a TypeError for BigInt. Handle it with a replacer: (key, val) => typeof val === 'bigint' ? val.toString() : val

Circular References

Objects that reference themselves will throw an error:

circular.js
javascript
const obj = { name: "Circular" };
obj.self = obj;  // Points to itself

JSON.stringify(obj);
// 💥 TypeError: Converting circular structure to JSON

// Solution: Use a library like 'flatted' or write custom replacer

Practical Examples

LocalStorage (Store Objects)

localstorage.js
javascript
// Save to localStorage
const settings = { theme: 'dark', fontSize: 16 };
localStorage.setItem('settings', JSON.stringify(settings));

// Load from localStorage
const saved = localStorage.getItem('settings');
const loadedSettings = saved ? JSON.parse(saved) : { theme: 'light', fontSize: 14 };

console.log(loadedSettings.theme); // "dark"

API Requests (Fetch)

fetch-api.js
javascript
// GET request - parse response
async function getUser(id) {
  const response = await fetch(`/api/users/${id}`);
  const user = await response.json();  // Built-in JSON parsing!
  return user;
}

// POST request - stringify body
async function createUser(userData) {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(userData)  // Stringify the body
  });
  return response.json();
}

Deep Clone Objects

deep-clone.js
javascript
// Quick and dirty deep clone (with limitations)
const original = {
  name: "Original",
  nested: { value: 42 }
};

const clone = JSON.parse(JSON.stringify(original));

clone.nested.value = 100;
console.log(original.nested.value); // Still 42 - truly cloned!

// Note: This doesn't work with functions, dates, undefined, etc.
// Use structuredClone() for a proper deep clone in modern browsers

Performance Tips

  • Parse once — Don't parse the same JSON multiple times. Cache the result.
  • Stringify carefully — Large objects with deep nesting are slow to stringify.
  • Use streaming parsers for huge JSON files (e.g., JSONStream for Node.js).
  • Consider Web Workers for parsing large JSON without blocking the UI.
performance.js
javascript
// Bad - parsing multiple times
function getName(jsonString) {
  return JSON.parse(jsonString).name;
}
function getAge(jsonString) {
  return JSON.parse(jsonString).age;
}

// Good - parse once, reuse
function getUserData(jsonString) {
  const user = JSON.parse(jsonString);
  return {
    name: user.name,
    age: user.age
  };
}

Common Errors and Solutions

Error Cause Solution
Unexpected token Invalid JSON syntax Validate your JSON, check for trailing commas
Unexpected end of JSON Truncated or incomplete JSON Check for complete braces/brackets
Converting circular structure Object references itself Use custom replacer or library
BigInt error BigInt not supported Convert to string in replacer
Debug your JSON! Use our JSON validator to find and fix syntax errors in your JSON instantly.

Frequently Asked Questions

What's the difference between JSON.parse() and eval()?

Never use eval() for JSON! It executes arbitrary code, creating massive security vulnerabilities. JSON.parse() only parses data — it's safe.

Can JSON.parse() handle single quotes?

No. JSON requires double quotes. {'name': 'Alice'} will throw an error. It must be {"name": "Alice"}.

How do I handle dates in JSON?

JSON doesn't have a date type. Dates are typically stored as ISO strings. Use a reviver function to convert them back to Date objects when parsing.

Is JSON.parse() synchronous?

Yes. For large JSON files, this can block the main thread. Use Web Workers or streaming parsers for huge datasets.

Keep Learning

About the Author

AT

Adam Tse

Founder & Lead Developer · 10+ years experience

Full-stack engineer with 10+ years of experience building developer tools and APIs. Previously worked on data infrastructure at scale, processing billions of JSON documents daily. Passionate about creating privacy-first tools that don't compromise on functionality.

JavaScript/TypeScript Web Performance Developer Tools Data Processing