The Parse-Serialize Cycle
Every language has built-in functions for these operations. The string form is used for storage, network transfer, and file I/O. The native object form is what you work with in code.
JavaScript
JSON.parse() — String to Object
1const jsonString = '{"name":"Alice","age":30}';23const user = JSON.parse(jsonString);45console.log(user.name); // "Alice"6console.log(user.age); // 307console.log(typeof user); // "object"JSON.stringify() — Object to String
1const user = {2 name: "Alice",3 age: 30,4 roles: ["admin", "editor"]5};67// Compact (for APIs / storage)8const compact = JSON.stringify(user);9// '{"name":"Alice","age":30,"roles":["admin","editor"]}'1011// Pretty-printed (for debugging / config files)12const pretty = JSON.stringify(user, null, 2);13// {14// "name": "Alice",15// "age": 30,16// "roles": ["admin", "editor"]17// }Error Handling (Critical)
1function safeJsonParse(text) {2 try {3 return { data: JSON.parse(text), error: null };4 } catch (err) {5 return { data: null, error: err.message };6 }7}89const result = safeJsonParse('{"valid": true}');10// { data: { valid: true }, error: null }1112const bad = safeJsonParse('{invalid}');13// { data: null, error: "Expected property name..." }Never Use eval()
eval(jsonString) to parse JSON. It executes arbitrary code and is a severe security vulnerability. Always use JSON.parse().The Reviver Function
JSON.parse() accepts an optional second argument — a reviver function that transforms values during parsing:
1const json = '{"created":"2026-03-28T12:00:00Z","name":"Task"}';23const obj = JSON.parse(json, (key, value) => {4 if (key === "created") return new Date(value);5 return value;6});78console.log(obj.created instanceof Date); // true9console.log(obj.created.getFullYear()); // 2026The Replacer Function
JSON.stringify() accepts a replacer to filter or transform values:
1const user = {2 name: "Alice",3 email: "[email protected]",4 password: "secret123",5 apiKey: "sk_live_abc..."6};78const safe = JSON.stringify(user, (key, value) => {9 if (key === "password" || key === "apiKey") return undefined;10 return value;11}, 2);1213// { "name": "Alice", "email": "[email protected]" }Python
1import json23# Parse (deserialize)4json_string = '{"name": "Alice", "age": 30}'5user = json.loads(json_string)6print(user["name"]) # Alice78# Serialize9user_dict = {"name": "Alice", "age": 30, "roles": ["admin"]}10json_output = json.dumps(user_dict, indent=2)11print(json_output)1213# File I/O14with open("data.json", "w") as f:15 json.dump(user_dict, f, indent=2)1617with open("data.json", "r") as f:18 loaded = json.load(f)Fetch API + JSON
The most common real-world usage — fetching JSON from an API:
1async function getUser(id) {2 const response = await fetch(`/api/users/${id}`);34 if (!response.ok) {5 throw new Error(`HTTP ${response.status}`);6 }78 const user = await response.json(); // parses JSON automatically9 return user;10}1112// Sending JSON to an API13async function createUser(data) {14 const response = await fetch("/api/users", {15 method: "POST",16 headers: { "Content-Type": "application/json" },17 body: JSON.stringify(data) // serializes to JSON18 });1920 return response.json();21}Language Comparison
| Operation | JavaScript | Python | Go | Java |
|---|---|---|---|---|
| Parse string | JSON.parse(s) | json.loads(s) | json.Unmarshal() | new ObjectMapper().readValue() |
| Serialize | JSON.stringify(o) | json.dumps(o) | json.Marshal() | mapper.writeValueAsString() |
| Read file | fs.readFileSync() | json.load(f) | json.NewDecoder(f) | mapper.readValue(file) |
| Write file | fs.writeFileSync() | json.dump(o, f) | json.NewEncoder(f) | mapper.writeValue(file) |
| Error type | SyntaxError | JSONDecodeError | error | JsonProcessingException |
Try It Yourself
This JSON represents an API response. Modify it to add a new user, change the pagination, or introduce an error to see what happens when you click Run & Validate.
Try It Yourself
Simulate an API response — modify and validate
Performance Tips
Avoid double-parsing
Never JSON.parse(JSON.stringify(obj)) to clone — use structuredClone() instead.
Stream large files
Use streaming parsers for files > 50MB to avoid memory issues.
Cache parsed results
Parse config files once at startup, not on every request.
Use response.json()
The Fetch API parses JSON in an optimized path — use it instead of text + parse.