{"id":10873,"library":"fast-safe-stringify","title":"Fast Safe Stringify","description":"fast-safe-stringify is a utility library designed for safely and quickly serializing JavaScript objects into JSON strings. It provides a robust alternative to the native `JSON.stringify`, specifically excelling at gracefully handling circular references within objects without throwing a `TypeError`. Instead, it intelligently replaces circular structures with a `[Circular]` string or `[...]` when configured limits are reached. The current stable version is 2.1.1, with recent updates (v2.1.0 and v2.1.1) introducing and refining `depthLimit` and `edgesLimit` options to prevent excessive recursion in complex objects. The library also offers a `stableStringify` function, which guarantees a deterministic output order for object keys, enhancing reproducibility. It is actively maintained and ships with TypeScript type definitions, making it suitable for modern JavaScript and TypeScript environments where predictable serialization of potentially self-referential data structures is crucial, such as in logging or API responses.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/davidmarkclements/fast-safe-stringify","tags":["javascript","stable","stringify","JSON","JSON.stringify","safe","serialize","typescript"],"install":[{"cmd":"npm install fast-safe-stringify","lang":"bash","label":"npm"},{"cmd":"yarn add fast-safe-stringify","lang":"bash","label":"yarn"},{"cmd":"pnpm add fast-safe-stringify","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"CommonJS is shown in documentation, but ESM is preferred for modern projects. The default export is the main stringify function.","wrong":"const safeStringify = require('fast-safe-stringify');","symbol":"safeStringify","correct":"import safeStringify from 'fast-safe-stringify';"},{"note":"stableStringify is a named export for deterministic serialization.","wrong":"import safeStringify.stableStringify from 'fast-safe-stringify';","symbol":"stableStringify","correct":"import { stableStringify } from 'fast-safe-stringify';"},{"note":"You can alias the default export for clarity, e.g., 'stringify' instead of 'safeStringify'.","symbol":"default as stringify","correct":"import stringify from 'fast-safe-stringify';"}],"quickstart":{"code":"import safeStringify, { stableStringify } from 'fast-safe-stringify';\n\nconst obj = { a: 1, b: 0 };\nobj.circular = obj;\nobj.anotherRef = obj;\n\nconsole.log('Original object with circular refs:', obj);\n\n// Using fast-safe-stringify to handle circular references\nconst safeSerialized = safeStringify(obj);\nconsole.log('\\nSafe Stringify Output (non-deterministic key order):', safeSerialized);\n// Expected: '{\"a\":1,\"b\":0,\"circular\":\"[Circular]\",\"anotherRef\":\"[Circular]\"}'\n\n// Using stableStringify for deterministic output order\nconst stableSerialized = stableStringify(obj);\nconsole.log('Stable Stringify Output (deterministic key order):', stableSerialized);\n// Expected: '{\"a\":1,\"b\":0,\"anotherRef\":\"[Circular]\",\"circular\":\"[Circular]\"}'\n\nconst deepCircular = { level1: { level2: {} } };\ndeepCircular.level1.level2.parent = deepCircular;\n\nconsole.log('\\nSafe Stringify with depth limit (default is MAX_SAFE_INTEGER):');\nconst limitedSerialized = safeStringify(deepCircular, null, 2, { depthLimit: 2 });\nconsole.log(limitedSerialized);\n// Expected: '{\\n  \"level1\": {\\n    \"level2\": \"[...]\"\\n  }\\n}'","lang":"javascript","description":"Demonstrates `safeStringify` and `stableStringify` handling circular references and optional depth limits."},"warnings":[{"fix":"Review and potentially adjust `depthLimit` or `edgesLimit` in the options object passed to `safeStringify` or `stableStringify` if previous behavior is desired for extremely complex objects.","message":"Version 2.1.0 introduced `depthLimit` and `edgesLimit` options. While defaults are set very high (`Number.MAX_SAFE_INTEGER`), code that implicitly relied on truly infinite recursion (e.g., in very rare, extremely deep structures) might now hit these limits, resulting in `[...]` instead of `[Circular]` for deeply nested references.","severity":"breaking","affected_versions":">=2.1.0"},{"fix":"Design your `replacer` functions to handle the `\"[Circular]\"` string explicitly if you need to modify or omit circular references, rather than expecting the object itself.","message":"When a circular reference is detected, the `replacer` function receives the string `\"[Circular]\"` as its `value` argument, not the original circular object itself. This prevents the `replacer` from directly inspecting or modifying the circular object.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Avoid side-effecting `toJSON` or `replacer` logic for circular references or for any part of the input object when using `stableStringify`. If such manipulation is critical, consider `safe-stable-stringify` (though noted as experimental) or manual pre-processing.","message":"Manipulating the input object or its circular structure within a `toJSON` method or a `replacer` function may not have the expected effect. For `safeStringify`, manipulating a circular structure in `toJSON` or `replacer` is not possible. For `stableStringify`, any modification to the input object within `toJSON` or `replacer` will be ignored, as the output is based on the initial shape of the value.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Replace `JSON.stringify` with `safeStringify` from `fast-safe-stringify`. Example: `const serialized = safeStringify(myObject);`","cause":"Attempting to serialize an object containing self-referencing properties or loops using `JSON.stringify`.","error":"TypeError: Converting circular structure to JSON"},{"fix":"Check the `value` argument within your `replacer` for the literal string `\"[Circular]\"` to handle circular references. For example: `if (value === '[Circular]') return;`","cause":"The `replacer` function is receiving the string `\"[Circular]\"` instead of the actual object, limiting modification capabilities.","error":"Replacer function not modifying circular reference as expected"}],"ecosystem":"npm"}