Skip to content
Back to Learn
·7 min read

Mastering JSON in JavaScript: Comprehensive Examples and Best Practices

JSON and JavaScript share a unique relationship — JSON syntax is derived directly from JavaScript object literal notation, making them naturally compatible. But despite this kinship, JSON and JavaScript objects have critical differences that every developer must understand. This guide covers JSON parsing, serialization, error handling, advanced patterns, and best practices for Node.js and browser environments. Use our JSON Formatter to visualize your data and JS Object to JSON converter to transform between formats.

JSON.parse(): Parsing JSON in JavaScript

The JSON.parse() method converts a JSON string into a JavaScript object. It has three behaviors you must know:

InputResultNotes
'{"name":"Alice"}'{name: "Alice"}Standard object parsing
'[1,2,3]'[1, 2, 3]Array parsing
'null'nullLiteral parsing
'undefined'SyntaxErrorundefined is not valid JSON
'{"key": undefined}'SyntaxErrorOnly null is valid for absence
// Always wrap in try/catch
try {
  const data = JSON.parse(jsonString);
  console.log(data.name);
} catch (error) {
  if (error instanceof SyntaxError) {
    console.error("Invalid JSON:", error.message, "at position",
      error.message.match(/position (d+)/)?.[1]);
  } else {
    throw error;
  }
}

JSON.stringify(): Serializing to JSON

The JSON.stringify() method converts a JavaScript value to a JSON string. Its full signature offers powerful options:

const obj = {
  name: "Alice",
  age: 30,
  active: true,
  score: null,
  tags: ["js", "json"],
  metadata: { version: 2 },
  createdAt: new Date()
};

// Basic usage
JSON.stringify(obj); // '{"name":"Alice","age":30,...}'

// Pretty print with 2-space indent
JSON.stringify(obj, null, 2);

// Custom replacer function
JSON.stringify(obj, (key, value) => {
  if (value instanceof Date) return value.toISOString();
  if (typeof value === 'undefined') return null;
  return value;
}, 2);

// Compact output for production
JSON.stringify(obj, null, 0);
// or with separators for max compaction
JSON.stringify(obj, (_, v) => v, null);

The Replacer Parameter: Advanced Filtering

The second parameter of JSON.stringify() can be a function or an array:

// Array of allowed keys (whitelist)
JSON.stringify(obj, ['name', 'age']); // Only includes name and age

// Function replacer
JSON.stringify(obj, (key, value) => {
  // Remove sensitive fields
  if (key === 'password' || key === 'ssn') return undefined;
  // Transform specific fields
  if (key === 'date') return new Date(value).toISOString();
  return value;
});

Handling Non-Serializable Values

JavaScript has values that do not survive JSON serialization:

ValueJSON.stringify() ResultSolution
undefinedOmitted from objects, becomes null in arraysUse null explicitly
NaNnullValidate numbers before serialization
InfinitynullUse finite numbers or null
FunctionOmittedCan not be serialized
SymbolOmittedUse string keys
Map{} (empty)Convert to array of entries first
Set{} (empty)Convert to array: [...set]
DateISO string (via toISOString())Works, but type is lost on re-parse

The reviver Parameter: Transforming During Parse

The second parameter of JSON.parse() is a reviver function that transforms values during parsing:

const json = '{"name":"Alice","birthDate":"1995-06-15T00:00:00.000Z"}';
const data = JSON.parse(json, (key, value) => {
  if (key === 'birthDate') return new Date(value);
  return value;
});
console.log(data.birthDate instanceof Date); // true

// Use with toJSON() for round-trip Date handling
const obj = {
  name: "Alice",
  date: new Date(),
  toJSON() {
    return { name: this.name, date: this.date.toISOString() };
  }
};

Circular References: The Silent Killer

Objects that reference themselves cause JSON serialization to throw — they must be handled:

const circular = { name: "Alice" };
circular.self = circular;
// JSON.stringify(circular); // TypeError: Converting circular structure to JSON

// Solution: Use a custom replacer or refactor
const seen = new WeakSet();
JSON.stringify(circular, (key, value) => {
  if (typeof value === 'object' && value !== null) {
    if (seen.has(value)) return '[Circular]';
    seen.add(value);
  }
  return value;
});

JSON in Node.js: Streams and File I/O

const fs = require('fs');

// Reading JSON files
const data = JSON.parse(fs.readFileSync('config.json', 'utf-8'));

// Writing JSON files
fs.writeFileSync('output.json', JSON.stringify(data, null, 2));

// For large JSON, use streaming
const readline = require('readline');
const rl = readline.createInterface({
  input: fs.createReadStream('large.ndjson')
});
rl.on('line', (line) => {
  const record = JSON.parse(line);
  // Process one record at a time
});

Common Pitfalls and Debugging Tips

  • Trailing commas — JavaScript objects allow them, JSON does not. Always validate with JSON Validator
  • Single quotes — Valid in JavaScript strings, invalid in JSON. Use JSON Fixer to convert
  • Unquoted keys — Valid in JavaScript objects, required in JSON
  • NaN/Infinity — Valid JavaScript numbers, invalid in JSON. Replace with null
  • BigInt — Not serializable. Convert to string: bigint.toString()
  • undefined properties — Silently dropped. Use null to explicitly represent absence

Next Steps

Practice these concepts with our JSON Formatter. Convert JavaScript objects to JSON with JS Object to JSON. For validation, use JSON Validator.