Safe Stable Stringify
safe-stable-stringify is a JavaScript utility that provides a deterministic and safe alternative to JSON.stringify. Currently at version 2.5.0, it offers consistent object key ordering, graceful handling of circular references, and configurable serialization of BigInt values, addressing common pitfalls of the native `JSON.stringify`. The library maintains a regular release cadence, frequently adding new options and performance improvements. Key differentiators include its configurable deterministic sorting using custom comparators, options to control maximum serialization depth and breadth, and the ability to define how circular references or BigInts are handled (e.g., replacement values, throwing errors, or omission). It ships with TypeScript types, supports both ESM and CommonJS modules, and has zero external dependencies, making it a robust choice for environments requiring reliable JSON serialization.
Common errors
-
TypeError: Do not know how to serialize a BigInt
cause Attempting to serialize a BigInt value using native `JSON.stringify`, or `safe-stable-stringify` with `bigint: false` and `strict: true`.fixUse `safe-stable-stringify` with the default `bigint: true` option (or explicitly set it), or provide a custom `replacer` function to handle BigInts. For `strict: true`, explicitly set `bigint: true` or `bigint: false` to ignore/convert. -
TypeError: Converting circular structure to JSON
cause Attempting to serialize an object with circular references using native `JSON.stringify`, or `safe-stable-stringify` configured to throw on circular references (`circularValue: Error`).fixConfigure `safe-stable-stringify` with `circularValue` set to a string (e.g., `'[Circular]'`), `null`, or `undefined` to handle circular references gracefully instead of throwing an error.
Warnings
- breaking Version 2.0.0 introduced breaking changes including default BigInt conversion to number (previously ignored), required ES6 environment, and full ESM support.
- breaking The default behavior for object key order became deterministic (sorted keys) in v2.0.0. If you relied on insertion order, you need to explicitly set `deterministic: false`.
- gotcha Boxed primitives (e.g., `Number(5)`, `Boolean(true)`) are treated as regular objects and not unboxed, unlike native `JSON.stringify`. This can lead to different serialization outputs for these specific values.
- gotcha Using the `strict` option verifies full JSON compatibility and will throw an error for non-JSON-compatible values (functions, `NaN`, `Infinity`), or if circular/BigInt values are present without explicit handling options. Sets, Maps, and Symbol keys are also not detected as incompatible.
- gotcha Earlier versions (prior to v2.3.1) could encounter 'invalid regexp group' errors in environments lacking negative lookbehind support for regular expressions (e.g., older browsers or Node.js versions).
Install
-
npm install safe-stable-stringify -
yarn add safe-stable-stringify -
pnpm add safe-stable-stringify
Imports
- stringify
import stringify from 'safe-stable-stringify'
import { stringify } from 'safe-stable-stringify' - configure
import configure from 'safe-stable-stringify'
import { configure } from 'safe-stable-stringify' - stringify (CJS)
const { stringify } = require('safe-stable-stringify')const stringify = require('safe-stable-stringify')
Quickstart
import { configure } from 'safe-stable-stringify';
const userObject = {
id: 123,
name: 'Alice',
settings: {
theme: 'dark',
notifications: true,
circularRef: null // Will be set later
},
roles: ['admin', 'user'],
creationDate: new Date(),
bigIntId: 9007199254740991123n // Example BigInt
};
userObject.settings.circularRef = userObject; // Create a circular reference
// Configure stringify for deterministic output, handling circular refs and BigInts
const stringify = configure({
deterministic: true, // Sort object keys alphabetically
circularValue: '[CIRCULAR_REF]', // Replace circular references with this string
bigint: true, // Convert BigInts to numbers
maximumDepth: 3 // Limit serialization depth
});
try {
const serialized = stringify(userObject, null, 2);
console.log(serialized);
// Expected output (order of keys will be stable, BigInt converted):
// {
// "bigIntId": 9007199254740991123,
// "creationDate": "2026-04-19T06:51:00.000Z", // Actual date will vary
// "id": 123,
// "name": "Alice",
// "roles": [
// "admin",
// "user"
// ],
// "settings": {
// "circularRef": "[CIRCULAR_REF]",
// "notifications": true,
// "theme": "dark"
// }
// }
} catch (error) {
console.error('Serialization error:', error.message);
}