json-stringify-safe vs fast-safe-stringify vs safe-json-stringify
安全なJSON文字列化ライブラリの比較
json-stringify-safefast-safe-stringifysafe-json-stringify類似パッケージ:

安全なJSON文字列化ライブラリの比較

fast-safe-stringifyjson-stringify-safesafe-json-stringify はいずれも JavaScript オブジェクトを JSON 文字列に安全に変換するためのユーティリティです。標準の JSON.stringify() は循環参照や特殊な値(例:undefined、関数)を含むオブジェクトでエラーを発生させることがありますが、これらのパッケージはその問題を回避し、アプリケーションのクラッシュを防ぎます。特に、エラーロギングやデバッグ情報のシリアル化など、信頼性が求められる場面で活用されます。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
json-stringify-safe32,805,907554-711年前ISC
fast-safe-stringify27,457,032357-94年前MIT
safe-json-stringify3,395,31858-38年前MIT

JSONの安全な文字列化:fast-safe-stringifyjson-stringify-safesafe-json-stringifyを比較

JavaScriptでオブジェクトをJSONに変換する際、循環参照や特殊な値(例:undefined、関数)が原因でJSON.stringify()がエラーを投げることがあります。この問題に対処するために設計されたのが、今回比較する3つのパッケージです。それぞれ異なるアプローチで「安全な」文字列化を実現していますが、内部の実装や使い勝手には明確な違いがあります。

🔄 循環参照の扱い方

fast-safe-stringify は、循環参照を検出して、その部分を"[Circular]"という文字列に置き換えます。これはデバッグ時に非常に役立ちます。

// fast-safe-stringify
const stringify = require('fast-safe-stringify');
const obj = { a: 1 };
obj.b = obj; // 循環参照
console.log(stringify(obj)); // {"a":1,"b":"[Circular]"}

json-stringify-safe も同様に循環参照を検出しますが、デフォルトでは循環参照のフィールドを完全に削除します。

// json-stringify-safe
const stringify = require('json-stringify-safe');
const obj = { a: 1 };
obj.b = obj;
console.log(stringify(obj)); // {"a":1}
// 'b' プロパティが消える

safe-json-stringify は、循環参照を検出した場合、その値をnullに置き換えます。

// safe-json-stringify
const stringify = require('safe-json-stringify');
const obj = { a: 1 };
obj.b = obj;
console.log(stringify(obj)); // {"a":1,"b":null}

💡 注意:json-stringify-safesafe-json-stringifyは、npm上で非推奨(deprecated) と明記されています。新規プロジェクトでの使用は避けてください。

⚙️ カスタマイズ性とAPI設計

fast-safe-stringify は、カスタムシリアライザーを渡すことで、循環参照以外の特殊な値(例:BigIntSymbol)の扱いも制御できます。

// fast-safe-stringify with custom serializer
const stringify = require('fast-safe-stringify');

function customSerializer(key, value) {
  if (typeof value === 'bigint') return value.toString();
  return value;
}

const obj = { id: 123n };
console.log(stringify(obj, customSerializer)); // {"id":"123"}

一方、json-stringify-safe は第3引数で循環参照時のプレースホルダーを指定できますが、柔軟性は低めです。

// json-stringify-safe with placeholder
const stringify = require('json-stringify-safe');
const obj = { a: 1 };
obj.b = obj;
console.log(stringify(obj, null, 2, () => '[Circular]'));
// {"a":1,"b":"[Circular]"}

safe-json-stringify はカスタマイズオプションがほとんどなく、単純な置換(null)のみを提供します。

🧪 特殊なJavaScript値の扱い

JSON.stringify()が通常扱えない値(undefined、関数、Symbolなど)に対して、各パッケージは次のように振る舞います。

  • fast-safe-stringify: undefinedや関数は削除され、Symbol"[object Symbol]"になる。
  • json-stringify-safe: undefinedや関数は削除される(標準JSON.stringifyと同じ)。
  • safe-json-stringify: 同様に削除されるが、内部でエラーが発生した場合は全体を空文字列""として返すことがある(信頼性に欠ける)。
// 比較例:関数とundefinedを含むオブジェクト
const obj = {
  valid: 'ok',
  fn: () => {},
  undef: undefined
};

// fast-safe-stringify → {"valid":"ok"}
// json-stringify-safe → {"valid":"ok"}
// safe-json-stringify → {"valid":"ok"}

ただし、fast-safe-stringifyはエラーハンドリングが堅牢で、予期しない例外が発生しても常に文字列を返します。

🚫 非推奨パッケージの現状

重要な点として、json-stringify-safesafe-json-stringify はどちらも公式に非推奨とされています。

  • json-stringify-safe のnpmページには「このパッケージはメンテナンスされていません。代わりに fast-safe-stringify を使ってください」と明記されています。
  • safe-json-stringify も同様に「非推奨」と表示されており、更新が長年停止しています。

これらのパッケージは、古いコードベースの互換性維持以外の目的では使用すべきではありません

✅ 実用的な推奨

  • 新規プロジェクトでは、fast-safe-stringify を使うべきです。速度、信頼性、カスタマイズ性のすべてで優れています。
  • 既存コードでjson-stringify-safeを使っている場合は、挙動の違い(循環参照が削除 vs [Circular])に注意して移行を検討してください。
  • safe-json-stringify は、非推奨かつ挙動が不安定なため、すぐに置き換えるべきです。

📊 まとめ:主な違い

パッケージ循環参照の扱いカスタマイズ性非推奨推奨度
fast-safe-stringify"[Circular]"に置換高(カスタムシリアライザー対応)⭐⭐⭐⭐⭐
json-stringify-safeフィールドを削除低(プレースホルダー指定のみ)
safe-json-stringifynullに置換ほぼなし

💡 結論

フロントエンド開発において、特にログ出力やエラートラッキングの文脈でオブジェクトを安全に文字列化する必要がある場合、fast-safe-stringify が唯一の現実的な選択肢です。他の2つは技術的に時代遅れであり、セキュリティや安定性のリスクを伴う可能性があります。シンプルで高速、そして信頼できるこのパッケージは、現代のJavaScriptアプリケーションにぴったりです。

選び方: json-stringify-safe vs fast-safe-stringify vs safe-json-stringify

  • json-stringify-safe:

    このパッケージは公式に非推奨とされており、新規プロジェクトでの使用は避けてください。既存コードで使われている場合のみ、互換性維持のために一時的に使用し、早急に fast-safe-stringify への移行を検討すべきです。循環参照がフィールドごと削除される点にも注意が必要です。

  • fast-safe-stringify:

    新規プロジェクトでは必ず fast-safe-stringify を選んでください。循環参照をわかりやすい [Circular] に置き換え、カスタムシリアライザーによる柔軟な拡張も可能で、パフォーマンスと信頼性の両面で優れています。非推奨ではない唯一の選択肢でもあります。

  • safe-json-stringify:

    このパッケージは非推奨であり、内部で予期しないエラーが発生すると空文字列を返すなど、信頼性に問題があります。新規プロジェクトでは絶対に使用せず、既存コードがあれば速やかに置き換えてください。

json-stringify-safe のREADME

json-stringify-safe

Like JSON.stringify, but doesn't throw on circular references.

Usage

Takes the same arguments as JSON.stringify.

var stringify = require('json-stringify-safe');
var circularObj = {};
circularObj.circularRef = circularObj;
circularObj.list = [ circularObj, circularObj ];
console.log(stringify(circularObj, null, 2));

Output:

{
  "circularRef": "[Circular]",
  "list": [
    "[Circular]",
    "[Circular]"
  ]
}

Details

stringify(obj, serializer, indent, decycler)

The first three arguments are the same as to JSON.stringify. The last is an argument that's only used when the object has been seen already.

The default decycler function returns the string '[Circular]'. If, for example, you pass in function(k,v){} (return nothing) then it will prune cycles. If you pass in function(k,v){ return {foo: 'bar'}}, then cyclical objects will always be represented as {"foo":"bar"} in the result.

stringify.getSerialize(serializer, decycler)

Returns a serializer that can be used elsewhere. This is the actual function that's passed to JSON.stringify.

Note that the function returned from getSerialize is stateful for now, so do not use it more than once.