fast-safe-stringify
Fast JSON.stringify drop-in that safely handles circular references
Repository Health
Technical Analysis
fast-safe-stringify is a minimal, dependency-free drop-in replacement for JSON.stringify that detects and safely replaces circular references instead of throwing. It exposes the same (obj, replacer, spacer) signature as the native JSON.stringify, so it can be swapped in without changing call sites, and adds an optional stable/stableStringify export that produces deterministic, key-sorted output for cases like content hashing or snapshot testing.
The implementation walks the object graph once to detect cycles and depth/edge limits before delegating the actual serialization to the native JSON.stringify, keeping performance close to the built-in while avoiding the TypeError: Converting circular structure to JSON failure mode. It has no runtime dependencies and ships a single ~230-line index.js file plus TypeScript typings.
What You Get
- A drop-in
stringify(obj, replacer, spacer, options)function matching the nativeJSON.stringifysignature - Automatic circular-reference detection, replacing cycles with a
[Circular]marker instead of throwing - Optional
depthLimitandedgesLimitoptions to cap traversal depth/breadth on very large or deep graphs - A
stringify.stable/stringify.stableStringifyvariant producing deterministic, key-sorted JSON output - Zero runtime dependencies and bundled TypeScript type definitions (
index.d.ts)
Common Use Cases
- Structured logging libraries that must serialize arbitrary application objects (including ones with circular references) without crashing
- Error reporting pipelines that stringify exception objects or request contexts of unknown shape
- Content hashing or cache-key generation where deterministic (
stable) key ordering is required - Debug/inspection tooling that dumps live in-memory objects to JSON for display or storage
Under The Hood
Architecture - The library is a single module (index.js) built around two mutually-recursive traversal functions: decirc for the default path and deterministicDecirc for the stable path. Both walk the object graph depth-first using an explicit stack array to detect cycles (rather than a WeakSet, for broader engine compatibility), and both temporarily rewrite offending properties in place — recording every mutation in a module-level arr array — so the original object can be fully restored in a finally block after JSON.stringify runs. setReplace additionally special-cases non-configurable getters by queuing them in a replacerStack that a wrapped replacer function (replaceGetterValues) consults during the real JSON.stringify call.
Tech Stack - Plain ES5-style JavaScript (var, no transpilation step) with a bundled index.d.ts for TypeScript consumers; zero runtime dependencies. Tests use tap, linting uses standard, and a benchmark.js script using the benchmark package compares performance against alternatives like json-stringify-safe.
Code Quality - Two test files (test.js, test-stable.js) run under tap and cover both the default and stable stringify paths, including circular-reference and getter-property cases. The temporary-mutation-then-restore approach is a deliberate trade-off for speed (avoiding cloning) but means the function is not safely reentrant/concurrent on the exact same object graph — an implicit constraint not documented in code comments, worth knowing before using it in highly concurrent contexts.
API Design - The default export mirrors JSON.stringify’s exact parameter order, making adoption a one-line import swap for existing logging code. The stable/stableStringify aliases on the same function object keep the two serialization modes discoverable without a second import, and depthLimit/edgesLimit options are opt-in with sane Number.MAX_SAFE_INTEGER defaults so existing callers see no behavior change until they choose to constrain output.
Used by 6 apps in this directory
APITable
Low Code Platforms · Databases
API-first collaborative spreadsheet-database platform that auto-generates REST APIs and lets teams build internal tools, CRMs, and dashboards without code.
MLflow
AI Development · Monitoring
The open source AI engineering platform for debugging, evaluating, monitoring, and optimizing production LLMs and agents at scale.
nango
Developer Tools · Automation · Authentication
Build product integrations with AI using 800+ APIs — auth, proxy, and TypeScript functions on production-grade infrastructure.
Omnivore
Knowledge Management · Bookmarks Archiving · Note Taking
Self-hosted read-it-later platform with highlights, newsletters, PDFs, and seamless Obsidian and Logseq integration.
Promptfoo
AI Development
An open-source CLI and library for evaluating and red-teaming LLM applications — replace trial-and-error prompt engineering with systematic evals, vulnerability scanning, and CI/CD integration.
strapi
CMS
Open-source headless CMS that auto-generates REST and GraphQL APIs from your content models, with a fully customizable admin panel you control.