Like JSON.stringify, but doesn't blow up on circular refs.
npx @tessl/cli install tessl/npm-json-stringify-safe@5.0.0JSON Stringify Safe provides a safe alternative to JSON.stringify that handles circular references gracefully instead of throwing errors. It offers the same API as the native JSON.stringify function but includes an additional cycleReplacer parameter for customizing how circular references are handled.
npm install json-stringify-safevar stringify = require('json-stringify-safe');ES Modules (if bundled appropriately):
import stringify from 'json-stringify-safe';var stringify = require('json-stringify-safe');
// Basic usage - handles circular references automatically
var circularObj = {};
circularObj.circularRef = circularObj;
circularObj.list = [circularObj, circularObj];
console.log(stringify(circularObj, null, 2));
// Output:
// {
// "circularRef": "[Circular ~]",
// "list": [
// "[Circular ~]",
// "[Circular ~]"
// ]
// }Main stringification function that safely converts objects to JSON strings without throwing on circular references.
/**
* Like JSON.stringify, but doesn't throw on circular references
* @param {any} obj - The object to stringify
* @param {function|array} [replacer] - JSON.stringify replacer parameter
* @param {number|string} [spaces] - JSON.stringify spaces parameter for formatting
* @param {function} [cycleReplacer] - Custom function to handle circular references
* @returns {string} JSON representation of the object
*/
function stringify(obj, replacer, spaces, cycleReplacer);Usage Examples:
var stringify = require('json-stringify-safe');
// Basic circular reference handling
var obj = { name: "Alice" };
obj.self = obj;
stringify(obj);
// Result: '{"name":"Alice","self":"[Circular ~]"}'
// With custom cycle replacer
var obj = { name: "Alice" };
obj.self = obj;
stringify(obj, null, null, function(key, value) {
return '[REMOVED]';
});
// Result: '{"name":"Alice","self":"[REMOVED]"}'
// With formatting and standard replacer
var obj = { name: "Alice", age: 25 };
obj.self = obj;
stringify(obj, function(key, value) {
return typeof value === 'string' ? value.toUpperCase() : value;
}, 2);
// Result: formatted JSON with "ALICE" instead of "Alice"
// Pruning cycles (return undefined)
var obj = { name: "Alice" };
obj.self = obj;
stringify(obj, null, null, function() {
return undefined;
});
// Result: '{"name":"Alice"}' (self property omitted)Returns a serializer function that can be used directly with JSON.stringify.
/**
* Returns a serializer that can be used elsewhere with JSON.stringify
* @param {function|array} [replacer] - JSON.stringify replacer parameter
* @param {function} [cycleReplacer] - Custom function to handle circular references
* @returns {function} A serializer function compatible with JSON.stringify
*/
stringify.getSerialize = function(replacer, cycleReplacer);Usage Examples:
var stringify = require('json-stringify-safe');
// Use with JSON.stringify directly
var obj = { a: "b" };
obj.circularRef = obj;
obj.list = [obj, obj];
var serializer = stringify.getSerialize();
var json = JSON.stringify(obj, serializer, 2);
// Result: formatted JSON with circular references handled
// With custom cycle replacer
var serializer = stringify.getSerialize(null, function(key, value) {
return null;
});
var json = JSON.stringify(obj, serializer);
// Result: '{"a":"b","circularRef":null,"list":[null,null]}'Important Note: The function returned from getSerialize is stateful and should not be reused. Create a new serializer for each stringification operation.
/**
* Function called when a circular reference is detected
* @param {string} key - The property key where the circular reference was found
* @param {any} value - The circular reference value
* @returns {any} Replacement value for the circular reference
*/
function cycleReplacer(key, value);"[Circular ~]""[Circular ~.path.to.object]" showing the path to the original object"[Circular ~.children.0]"The cycleReplacer function receives:
key: The property name where the circular reference was detectedvalue: The actual circular reference objectthis: The parent object containing the circular referenceReturn values:
null: Explicitly sets the property to nullundefined: Removes the property from the output entirelyvar obj = { name: "Alice", child: { name: "Bob" } };
obj.child.parent = obj;
stringify(obj);
// Result includes: "parent": "[Circular ~]"
var obj = { users: [{ name: "Alice" }] };
obj.users[0].root = obj;
stringify(obj);
// Result includes: "root": "[Circular ~]"
obj.users[0].self = obj.users[0];
stringify(obj);
// Result includes: "self": "[Circular ~.users.0]"cycleReplacer function returns a circular reference itselfJSON.stringify function (e.g., functions, undefined values, symbols when not handled by replacer)JSON.stringify with optional fourth parameterJSON.stringifyJSON.stringify support)