JSON.parse() and JSON.stringify()
Basic Parsing
Parse JSON safelyjavascript
1const jsonString = '{"name":"Alice","age":28}';23try {4 const user = JSON.parse(jsonString);5 console.log(user.name); // "Alice"6} catch (err) {7 console.error('Invalid JSON:', err.message);8}Stringify with Formatting
Pretty-print JSONjavascript
1const data = { name: "Alice", scores: [98, 87, 95] };23// Compact (for APIs, storage)4JSON.stringify(data);5// '{"name":"Alice","scores":[98,87,95]}'67// Pretty (for debugging, logs)8JSON.stringify(data, null, 2);9// '{10// "name": "Alice",11// "scores": [98, 87, 95]12// }'Replacer and Reviver
Transform during parse/stringifyjavascript
1// Reviver: transform values during parse2const json = '{"created":"2026-03-28T10:00:00Z","name":"Alice"}';3const data = JSON.parse(json, (key, value) => {4 if (key === 'created') return new Date(value);5 return value;6});7// data.created is now a Date object89// Replacer: filter/transform during stringify10const user = { name: "Alice", password: "secret123", age: 28 };11JSON.stringify(user, (key, value) => {12 if (key === 'password') return undefined; // strip sensitive fields13 return value;14}, 2);15// { "name": "Alice", "age": 28 }Fetching JSON from APIs
Production-ready fetch patternjavascript
1async function fetchUsers() {2 const response = await fetch('https://api.example.com/users', {3 headers: { 'Accept': 'application/json' },4 signal: AbortSignal.timeout(10_000),5 });67 if (!response.ok) {8 throw new Error(`HTTP ${response.status}: ${response.statusText}`);9 }1011 const contentType = response.headers.get('content-type');12 if (!contentType?.includes('application/json')) {13 throw new Error(`Expected JSON, got ${contentType}`);14 }1516 return response.json(); // returns parsed object17}1819// Usage with error boundary20try {21 const users = await fetchUsers();22 console.log(`Loaded ${users.length} users`);23} catch (err) {24 if (err.name === 'TimeoutError') {25 console.error('Request timed out');26 } else {27 console.error('Fetch failed:', err.message);28 }29}Always Check response.ok
fetch() does not throw on HTTP 4xx/5xx errors. A 404 Not Found is a successful fetch that returns a response with ok: false. Always check before calling .json().localStorage and sessionStorage
Safe localStorage wrapperjavascript
1function saveJson(key, data) {2 try {3 localStorage.setItem(key, JSON.stringify(data));4 return true;5 } catch (err) {6 // QuotaExceededError if storage is full (~5-10 MB limit)7 console.warn('Failed to save:', err.message);8 return false;9 }10}1112function loadJson(key, fallback = null) {13 try {14 const raw = localStorage.getItem(key);15 return raw ? JSON.parse(raw) : fallback;16 } catch {17 return fallback; // corrupted data returns fallback18 }19}2021// Usage22saveJson('preferences', { theme: 'dark', fontSize: 16 });23const prefs = loadJson('preferences', { theme: 'light', fontSize: 14 });Storage Limits
localStorage has a ~5-10 MB limit per origin. For larger data, use IndexedDB. Never store sensitive data (tokens, passwords) in localStorage — it's accessible to any JavaScript on the same origin.Importing JSON Files
Static Import (Build Time)
Import assertion (ES2025+)javascript
1// Works in Node.js 20+, modern bundlers2import config from './config.json' with { type: 'json' };3console.log(config.database.host);Dynamic Import (Runtime)
Lazy loading JSONjavascript
1async function loadTranslations(lang) {2 const module = await import(`./locales/${lang}.json`, {3 with: { type: 'json' }4 });5 return module.default;6}78const en = await loadTranslations('en');Fetch from Public Directory
Load JSON file at runtime (browser)javascript
1const response = await fetch('/data/countries.json');2const countries = await response.json();Deep Cloning with JSON
JSON clone vs structuredClonejavascript
1const original = { name: "Alice", scores: [98, 87] };23// JSON method (old pattern — has limitations)4const clone1 = JSON.parse(JSON.stringify(original));56// structuredClone (modern — handles more types)7const clone2 = structuredClone(original);89// JSON clone fails with: Date, Map, Set, RegExp, undefined, Infinity, circular refs10// structuredClone handles all of these correctly| Feature | JSON Clone | structuredClone |
|---|---|---|
| Date objects | ✗ (becomes string) | ✓ |
| Map / Set | ✗ (becomes {}) | ✓ |
| undefined | ✗ (dropped) | ✓ |
| Circular references | ✗ (throws) | ✓ |
| Functions | ✗ | ✗ |
| Performance | Slower | Faster |
| Browser support | All | All modern (2022+) |
Web Workers and JSON
Offload heavy JSON parsing to a Workerjavascript
1// main.js2const worker = new Worker('/json-worker.js');3worker.postMessage({ action: 'parse', data: hugeJsonString });45worker.onmessage = (event) => {6 const { result, error } = event.data;7 if (error) console.error(error);8 else console.log('Parsed:', result);9};1011// json-worker.js12self.onmessage = (event) => {13 const { action, data } = event.data;14 if (action === 'parse') {15 try {16 const result = JSON.parse(data);17 self.postMessage({ result });18 } catch (err) {19 self.postMessage({ error: err.message });20 }21 }22};Tip
Parsing JSON over 1 MB blocks the main thread. Use a Web Worker to keep the UI responsive. Our JSON Viewer uses this pattern for large files.
Common Pitfalls
| Pitfall | Example | Fix |
|---|---|---|
| Double parsing | JSON.parse(JSON.parse(str)) | Parse once — check if input is string or object |
| Stringify drops undefined | {a: undefined} → "{}" | Use replacer to convert undefined to null |
| Date serialization | Date → ISO string after stringify | Use reviver to restore Date objects |
| BigInt not supported | JSON.stringify({n: 1n}) throws | Use replacer to convert BigInt to string |
| Circular references | obj.self = obj → throws | Use a custom replacer or structuredClone |
| NaN / Infinity | Become null in JSON | Validate numbers before serialization |
Try These Tools
Try It Yourself
Try modifying this JSON and validating it — this is exactly what JSON.parse() does under the hood.
Try It Yourself
This is the JSON your fetch() call would return
Continue Learning
Frequently Asked Questions
What is the difference between JSON and a JavaScript object?
A JavaScript object is a runtime data structure. JSON is a text format. JSON requires double-quoted keys and strings, does not allow functions, undefined, or trailing commas. JSON.parse() converts JSON text into a JS object; JSON.stringify() does the reverse.
Can I import a JSON file in JavaScript?
Yes. Use import data from "./data.json" with { type: "json" } (import assertions) in modern environments, or use fetch() to load JSON files dynamically.
How do I store JSON in localStorage?
localStorage only stores strings. Use JSON.stringify(data) when saving and JSON.parse(localStorage.getItem(key)) when reading. Always wrap parse in try/catch for safety.
Why does JSON.stringify skip undefined values?
By design, JSON has no "undefined" type. JSON.stringify() silently drops keys with undefined values in objects and converts undefined array elements to null. Use a replacer function to handle this if needed.
Is JSON.parse safe from injection attacks?
JSON.parse() itself is safe — it only parses data, not executable code. However, if you insert parsed data into HTML without escaping, you are vulnerable to XSS. Always sanitize before rendering in the DOM.