How to Convert a JavaScript Object to a JSON String — JSON.stringify() Explained
Every JavaScript developer needs to convert objects to JSON strings — for API requests, localStorage, config files, logs, and test fixtures. This guide explains every way to do it: JSON.stringify() for standard cases, the space parameter for readable output, the replacer for filtering sensitive fields, and the free online tool for instant conversion without writing any code.
JSON.stringify()
The built-in JS method — no install, works in every browser and Node.js
null, 2
The magic second and third arguments for pretty-printed output
5 ways
Different methods to serialize objects — each best for different scenarios
The Simplest Way: JSON.stringify(object)
For the most common case — serializing a plain JavaScript object to a compact JSON string — pass the object directly to JSON.stringify() with no other arguments.
// Plain JavaScript object
const user = {
id: 42,
name: 'Alice',
email: 'alice@example.com',
age: 28,
isActive: true,
tags: ['admin', 'editor'],
};
// Convert to JSON string
const jsonString = JSON.stringify(user);
console.log(jsonString);
// '{"id":42,"name":"Alice","email":"alice@example.com","age":28,"isActive":true,"tags":["admin","editor"]}'
console.log(typeof jsonString); // 'string'
// Round-trip: parse it back to an object
const parsedBack = JSON.parse(jsonString);
console.log(parsedBack.name); // 'Alice'Result is always a string
JSON.stringify() always returns a string (or undefined for non-JSON-representable inputs). The quotes around keys and string values, the colon separators, and the lack of trailing commas are all part of valid JSON format — required by the spec.Pretty-Print: Readable Multi-Line JSON String
The default output is a compact single line — hard to read for complex objects. Pass a space value as the third argument to get indented, multi-line output.
const config = {
server: {
host: 'api.example.com',
port: 443,
ssl: true,
},
database: {
host: 'db.internal',
port: 5432,
name: 'production',
},
features: ['auth', 'analytics', 'notifications'],
};
// Compact — for sending over the network
const compact = JSON.stringify(config);
// '{"server":{"host":"api.example.com","port":443,"ssl":true},...}'
// Pretty — for config files, debugging, logs
const pretty = JSON.stringify(config, null, 2);
console.log(pretty);
// {
// "server": {
// "host": "api.example.com",
// "port": 443,
// "ssl": true
// },
// "database": {
// "host": "db.internal",
// "port": 5432,
// "name": "production"
// },
// "features": [
// "auth",
// "analytics",
// "notifications"
// ]
// }
// 4-space indent — common in Python ecosystem
const wide = JSON.stringify(config, null, 4);
// Tab indent — common in some editors
const tabbed = JSON.stringify(config, null, ' ');null, 2 — the most used stringify call
JSON.stringify(obj, null, 2) is the most common form after the basic one-argument call. The null skips the replacer (no field filtering), and 2 adds 2-space indentation. It appears in config generation, test fixtures, pretty-printing API responses, and writing JSON files in Node.js.
Filter Fields — Only Include What You Need
When an object has sensitive data, internal fields, or too many properties for the use case, the replacer parameter filters the output.
const user = {
id: 42,
name: 'Alice',
email: 'alice@example.com',
passwordHash: '$2b$10$...',
apiKey: 'sk-live-abc123',
sessionToken: 'tok_xyz',
createdAt: '2024-01-15',
updatedAt: '2024-11-10',
};
// Only serialize id, name, email — everything else is omitted
const publicUser = JSON.stringify(user, ['id', 'name', 'email'], 2);
// {
// "id": 42,
// "name": "Alice",
// "email": "alice@example.com"
// }
// passwordHash, apiKey, sessionToken, createdAt, updatedAt are NOT includedconst record = {
id: 'rec-001',
title: 'Q4 Report',
content: 'Full report content...',
author: 'Alice',
internalNotes: 'Draft — do not share',
_metadata: { version: 3, checksum: 'abc123' },
publishedAt: new Date('2024-11-01'),
};
// Function: called for every key-value pair at every depth
const cleanReplacer = (key, value) => {
if (key === '') return value; // always return root object
if (key.startsWith('_')) return undefined; // omit private _fields
if (key === 'internalNotes') return undefined;
return value;
};
JSON.stringify(record, cleanReplacer, 2);
// {
// "id": "rec-001",
// "title": "Q4 Report",
// "content": "Full report content...",
// "author": "Alice",
// "publishedAt": "2024-11-01T00:00:00.000Z"
// }Convert Nested Objects and Arrays
JSON.stringify() handles nested objects and arrays recursively. The depth is unlimited — it serializes the entire object graph in one call.
const order = {
id: 'ORD-9001',
customer: {
id: 'CUST-42',
name: 'Alice Smith',
address: {
street: '123 Main St',
city: 'London',
country: 'UK',
postcode: 'EC1A 1BB',
},
},
items: [
{ sku: 'PROD-1', name: 'Widget A', qty: 2, price: 9.99 },
{ sku: 'PROD-2', name: 'Widget B', qty: 1, price: 19.99 },
],
total: 39.97,
status: 'pending',
createdAt: new Date().toISOString(),
};
const json = JSON.stringify(order, null, 2);
// Produces a fully nested, 30+ line JSON string
// Every array item gets its own indented block
// Date is already an ISO stringConverting Objects in Common Scenarios
const newProduct = {
name: 'Wireless Mouse',
price: 29.99,
category: 'electronics',
inStock: true,
tags: ['wireless', 'peripheral', 'office'],
};
const response = await fetch('https://api.example.com/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN',
},
body: JSON.stringify(newProduct), // MUST be a string — not an object
});
const created = await response.json();
console.log('Created product ID:', created.id);// localStorage can only store strings
const userPreferences = {
theme: 'dark',
language: 'en',
notifications: { email: true, push: false, sms: false },
dashboardWidgets: ['revenue', 'users', 'conversion'],
};
// Save
localStorage.setItem('prefs', JSON.stringify(userPreferences));
// Load
const prefs = JSON.parse(localStorage.getItem('prefs') ?? '{}');
console.log(prefs.theme); // 'dark'
console.log(prefs.notifications.email); // trueimport fs from 'fs';
const data = {
version: '2.1.0',
generatedAt: new Date().toISOString(),
users: [
{ id: 1, name: 'Alice', role: 'admin' },
{ id: 2, name: 'Bob', role: 'viewer' },
],
};
// Write with 2-space indent for human-readable JSON files
fs.writeFileSync('./output/users.json', JSON.stringify(data, null, 2), 'utf8');
// For compact files (smaller, machine-readable)
fs.writeFileSync('./cache/users.min.json', JSON.stringify(data), 'utf8');// Many log transports expect string values or JSON serializable structures
// JSON.stringify prevents [object Object] in string concatenation
const requestContext = {
requestId: 'req-abc123',
userId: 42,
path: '/api/orders',
method: 'POST',
durationMs: 143,
};
// Simple string concat — broken
console.log('Request finished: ' + requestContext);
// 'Request finished: [object Object]' ← not useful
// Correct
console.log('Request finished:', JSON.stringify(requestContext));
// 'Request finished: {"requestId":"req-abc123","userId":42,...}'What JSON.stringify() Cannot Convert
Not all JavaScript values can be represented in JSON. Knowing which values get silently dropped vs. which throw errors saves hours of debugging.
undefined → omitted or null
In object properties: silently omitted. In arrays: becomes null (to preserve index). As the top-level value: returns the JS value undefined (not a string). Use null to represent intentionally absent values.
Functions → omitted
Object properties with function values are silently omitted. Functions in arrays become null. JSON cannot represent executable code — this is intentional for security. Classes serialize as empty objects {} unless they have toJSON().
Symbol → omitted
Symbol-keyed properties are always omitted. Symbol values in objects are omitted; in arrays they become null. Symbols are JavaScript-internal identifiers with no JSON equivalent.
Circular references → throws
If an object references itself (directly or indirectly), JSON.stringify() throws TypeError: "Converting circular structure to JSON". Use the flatted package or a custom replacer that tracks seen objects to handle circular structures.
BigInt → throws
JSON.stringify() throws TypeError: "Do not know how to serialize a BigInt". Convert BigInt to string or number first: JSON.stringify({ id: bigIntValue.toString() }). JSON numbers have precision limits that BigInt was designed to exceed.
Date → ISO string (via toJSON)
Date objects have a built-in toJSON() method that produces an ISO 8601 string. So JSON.stringify(new Date()) produces the current time as a quoted string — not a Date object. Parsing it back gives a string, not a Date; re-construct with new Date(str).
Forgetting that functions in objects are silently dropped
Functions silently vanish — no warning, no error
const service = {
name: 'UserService',
baseUrl: 'https://api.example.com',
fetch: async (id) => { /* ... */ }, // a method
validate: (data) => data.id > 0, // another method
};
JSON.stringify(service);
// '{"name":"UserService","baseUrl":"https://api.example.com"}'
// fetch and validate silently disappeared!
// Logging this gives a false picture of the objectExplicitly define what to serialize via toJSON() or plain data object
// Option 1: build a plain serializable object for logging/transfer
const serializable = {
name: service.name,
baseUrl: service.baseUrl,
// methods listed by name only for documentation
methods: ['fetch', 'validate'],
};
JSON.stringify(serializable, null, 2);
// Option 2: use .toJSON() to control serialization
class UserService {
constructor() { this.name = 'UserService'; this.baseUrl = '...'; }
toJSON() { return { name: this.name, baseUrl: this.baseUrl }; }
async fetch(id) { /* ... */ }
}Use the JSON.stringify() Online Tool
For converting complex objects without opening a browser console or Node.js REPL, the online tool handles it instantly.
Paste your JavaScript object
The tool accepts JavaScript object literals with unquoted keys, single-quoted strings, trailing commas, and comments — not just strict JSON. It normalizes the input automatically.
Choose compact or pretty output
Select your indent level — compact (0), 2-space, 4-space, or tab. The byte count updates instantly so you can see the size difference.
Review the JSON string
The output is the exact string JSON.stringify() produces: all keys quoted, special characters escaped, undefined removed, null and boolean values correctly formatted.
Copy or download the result
Copy the JSON string to your clipboard for pasting into code, or download as a .json file for use in fixtures, mock data, or config files.
Convert any JS object to JSON string instantly