{"_id":"canonical-json","_rev":"14-a18ee2bdc7e5788c831d1af76ab9da4e","name":"canonical-json","dist-tags":{"latest":"0.4.0"},"versions":{"0.0.1":{"name":"canonical-json","version":"0.0.1","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"BSD","_id":"canonical-json@0.0.1","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"homepage":"https://github.com/mirkok/canonical-json","dist":{"shasum":"c7f35c1c95fcedec3cd682a54285b3d509362ccf","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.1.tgz","integrity":"sha512-quOc9Xloom+88ay9BKxrPVeZhSYTkWHbjW09yMelUqNAcEQWTjWSftKuhiiHaIO/lpH5pKYEVRzSvAAOeMZ5hQ==","signatures":[{"sig":"MEUCIQCFzTe2+gRUkkKQWdfuyKpqxWbq/7iGW4wukrIaUTNsQgIgKz5JG5ueg2rW3fU3U2CqJlUy02Uei0L9vOjFtXHOasI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","scripts":{"test":"node_modules/.bin/mocha test/index.js"},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"repository":"","_npmVersion":"1.1.65","description":"a canonical json implementation","directories":{}},"0.0.3":{"name":"canonical-json","version":"0.0.3","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"BSD","_id":"canonical-json@0.0.3","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"homepage":"https://github.com/mirkokiefer/canonical-json","dist":{"shasum":"b161991cacf192e1068203557fbf99fce61ca397","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.3.tgz","integrity":"sha512-mywPMiT1JTQ5OWg0UgKu5G1yj+SbBfnUIPHOBI6IZUw9ywd65IIDq2pHusf1WQKforXOkysyghtwojBY5UzAtA==","signatures":[{"sig":"MEQCIEQ5vS03Cf8gU9sOCM79i0QD+KzBaSZblAmNOL1/4v2qAiAbhiGzy3JzWJBC7RkMsRLixRMC76KITgm6XmilTgM5BQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","scripts":{"test":"node_modules/.bin/mocha test/index.js"},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"repository":"","_npmVersion":"1.2.16","description":"a canonical json implementation","directories":{}},"0.0.4":{"name":"canonical-json","version":"0.0.4","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"BSD","_id":"canonical-json@0.0.4","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"homepage":"https://github.com/mirkokiefer/canonical-json","bugs":{"url":"https://github.com/mirkokiefer/canonical-json/issues"},"dist":{"shasum":"6579c072c3db5c477ec41dc978fbf2b8f41074a3","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.4.tgz","integrity":"sha512-2sW7x0m/P7dqEnO0O87U7RTVQAaa7MELcd+Jd9FA6CYgYtwJ1TlDWIYMD8nuMkH1KoThsJogqgLyklrt9d/Azw==","signatures":[{"sig":"MEUCIQCHOjCVS8HlMNQB25AVyJScn5zQH+LEG4nUc0+VdXnZuAIgEw7QBCeP94ZQnHzw68kShQalCvEGp0g9tNr4H+ClEaI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","scripts":{"test":"node_modules/.bin/mocha test/index.js"},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"repository":{"url":"https://github.com/mirkokiefer/canonical-json.git","type":"git"},"_npmVersion":"1.3.5","description":"a canonical json implementation","directories":{}},"0.1.0":{"name":"canonical-json","version":"0.1.0","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"MIT","_id":"canonical-json@0.1.0","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"homepage":"https://github.com/mirkokiefer/canonical-json","bugs":{"url":"https://github.com/mirkokiefer/canonical-json/issues"},"bin":{"canonical-json":"canonical-json.js"},"dist":{"shasum":"87e35b8eccacd269ebe76a2f60f839236ea3ab2e","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.1.0.tgz","fileCount":14,"integrity":"sha512-sJ80hUzw/zBjwJ3Jb6mm/bfyk2JFG4EirhO9o6ILEFXAmyQIK+GUjgYxLEcsqMldJqS5a4IPtf7jnBtDJSEbrw==","signatures":[{"sig":"MEUCIQCrDU89GcFQTj1hH1YIjqoAXrE/AyQc1so/k5cug4//kQIgIoGsgGXtWjzPtElVbvZWHxyZdRTBM1qb2ZNwNOLZxZ8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12071},"main":"index.js","type":"module","types":"./index.d.ts","gitHead":"70031fdc2eef1f2dde96cb3383cc8f53e2c458b7","scripts":{"test":"mocha test.mjs"},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"repository":{"url":"git+https://github.com/mirkokiefer/canonical-json.git","type":"git"},"_npmVersion":"10.8.1","description":"a canonical json implementation","directories":{},"_nodeVersion":"20.16.0","_hasShrinkwrap":false,"devDependencies":{"mocha":"^10.0.0","@types/node":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/canonical-json_0.1.0_1746090569365_0.46073105056822006","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"canonical-json","version":"0.2.0","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"MIT","_id":"canonical-json@0.2.0","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"homepage":"https://github.com/mirkokiefer/canonical-json","bugs":{"url":"https://github.com/mirkokiefer/canonical-json/issues"},"bin":{"canonical-json":"canonical-json.js"},"dist":{"shasum":"ff5982a3dec9050310bf22b056eff93459304008","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.2.0.tgz","fileCount":14,"integrity":"sha512-xeH/NgtNA7kIuKSxopJVdXqCKWyDB79aqxQRQ9FV02fvmqW7DSnjoFyzAUrBpfbwjU6lwTYOLc+HM6KupbsfVQ==","signatures":[{"sig":"MEUCIG+kSQucFskCMoytAcpmWilPdYXoJOwjZ8hrYkQtxRlQAiEA/FOuSt+urR48Rx16QS7Y7MJC01QvAECgPXnurULKBJw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13781},"main":"index.js","type":"module","types":"./index.d.ts","gitHead":"7b4398893edb74a58a34a8ded7fd1a7180f77d4b","scripts":{"test":"mocha test.mjs"},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"repository":{"url":"git+https://github.com/mirkokiefer/canonical-json.git","type":"git"},"_npmVersion":"10.8.1","description":"a canonical json implementation","directories":{},"_nodeVersion":"20.16.0","_hasShrinkwrap":false,"devDependencies":{"mocha":"^10.0.0","@types/node":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/canonical-json_0.2.0_1746091125537_0.7689810138685569","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"canonical-json","version":"0.4.0","description":"a canonical json implementation","type":"module","main":"index.js","exports":{".":{"types":"./index.d.ts","import":"./index.js"},"./hash":{"types":"./hash.d.ts","import":"./hash.js"}},"types":"index.d.ts","bin":{"canonical-json":"canonical-json.js"},"scripts":{"test":"node --test test.js"},"keywords":["json","canonical","deterministic","stringify","sorted","stable"],"engines":{"node":">=14"},"repository":{"type":"git","url":"git+https://github.com/mirkokiefer/canonical-json.git"},"homepage":"https://github.com/mirkokiefer/canonical-json","author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"MIT","gitHead":"fa8ca68df9c8a7e0470a0096963bef5eb4a510a7","_id":"canonical-json@0.4.0","bugs":{"url":"https://github.com/mirkokiefer/canonical-json/issues"},"_nodeVersion":"22.17.0","_npmVersion":"11.12.0","dist":{"integrity":"sha512-tjdV5Z1ZYX7JfotmcutLzAiwzw0XiViJB9smqVM7sIoOp+IdqRZcnqfFLzHdb9/baDzkNI0ECfLoMt+EBOYx4A==","shasum":"5c5940462610438859533a3447d25f356697b53c","tarball":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.4.0.tgz","fileCount":11,"unpackedSize":13871,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHXczVD05tsFI21OZ7KwkVG2gfsYlhkAaXPCZp+P6Vx9AiEA35wIIq+CgN3XPexSKpyAA9gZjdi65hR6ddXqr1S2jqI="}]},"_npmUser":{"name":"mirkok","email":"mail@mirkokiefer.com"},"directories":{},"maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/canonical-json_0.4.0_1774323837919_0.7745541116085126"},"_hasShrinkwrap":false}},"time":{"created":"2013-01-29T11:02:38.519Z","modified":"2026-03-24T03:43:58.473Z","0.0.1":"2013-01-29T11:02:44.611Z","0.0.3":"2013-06-07T01:25:40.216Z","0.0.4":"2014-02-06T19:37:18.115Z","0.1.0":"2025-05-01T09:09:29.610Z","0.2.0":"2025-05-01T09:18:45.724Z","0.4.0":"2026-03-24T03:43:58.056Z"},"bugs":{"url":"https://github.com/mirkokiefer/canonical-json/issues"},"author":{"name":"Mirko Kiefer","email":"mail@mirkokiefer.com"},"license":"MIT","homepage":"https://github.com/mirkokiefer/canonical-json","repository":{"type":"git","url":"git+https://github.com/mirkokiefer/canonical-json.git"},"description":"a canonical json implementation","maintainers":[{"name":"mirkok","email":"mail@mirkokiefer.com"}],"readme":"[![npm version](https://img.shields.io/npm/v/canonical-json.svg)](https://www.npmjs.com/package/canonical-json)\n[![tests](https://github.com/mirkokiefer/canonical-json/actions/workflows/test.yml/badge.svg)](https://github.com/mirkokiefer/canonical-json/actions)\n\n# canonical-json - Deterministic JSON.stringify()\n\nA drop-in replacement for `JSON.stringify` that produces **deterministic**, **canonical JSON** output compliant with [RFC 8785 (JSON Canonicalization Scheme)](https://www.rfc-editor.org/rfc/rfc8785).\n\nIdeal for content-addressable hashing, digital signatures, and distributed systems where identical objects must produce identical bytes.\n\n## Install\n\n```bash\nnpm install canonical-json\n```\n\n## Usage\n\n```js\nimport stringify from 'canonical-json'\n\nstringify({ b: 2, a: 1, c: { y: 0, x: 9 } })\n// '{\"a\":1,\"b\":2,\"c\":{\"x\":9,\"y\":0}}'\n```\n\n### Replacer\n\nSupports both function and array replacers, just like `JSON.stringify`:\n\n```js\nstringify({ a: 1, b: 2, c: 3 }, ['a', 'c'])\n// '{\"a\":1,\"c\":3}'\n\nstringify({ a: 1, b: 2 }, (key, value) => key === 'b' ? undefined : value)\n// '{\"a\":1}'\n```\n\n### Indentation\n\n```js\nstringify({ a: 1 }, null, 2)\n// '{\\n  \"a\": 1\\n}'\n```\n\n### Custom Key Order\n\nPass a comparator function as the fourth argument:\n\n```js\nconst order = { first: 1, second: 2, third: 3 }\nconst cmp = (a, b) => (order[a] || 9999) - (order[b] || 9999)\n\nstringify({ third: 'c', first: 'a', second: 'b' }, null, null, cmp)\n// '{\"first\":\"a\",\"second\":\"b\",\"third\":\"c\"}'\n```\n\n### Streaming with `walk`\n\n`walk` traverses the value and streams canonical JSON chunks to a callback — without building the full string:\n\n```js\nimport { createHash } from 'node:crypto'\nimport { walk } from 'canonical-json'\n\nconst hasher = createHash('sha256')\nwalk(obj, chunk => hasher.update(chunk))\nconst digest = hasher.digest('hex')\n```\n\n### Convenience hashing\n\nFor Node.js/Bun/Deno, a separate entry point provides one-liner hashing without pulling `node:crypto` into browser builds:\n\n```js\nimport { hash } from 'canonical-json/hash'\n\nhash(obj)              // sha256 hex digest\nhash(obj, 'md5')       // md5 hex digest\nhash(obj, 'sha512')    // sha512 hex digest\n```\n\n## API\n\n```ts\n// canonical-json\nexport default function stringify(\n  value: any,\n  replacer?: ((key: string, value: any) => any) | string[],\n  space?: string | number,\n  keyCompare?: (a: string, b: string) => number\n): string | undefined\n\nexport function walk(\n  value: any,\n  write: (chunk: string) => void,\n  keyCompare?: (a: string, b: string) => number\n): void\n\n// canonical-json/hash (Node.js/Bun/Deno only)\nexport function hash(\n  value: any,\n  algorithm?: string,    // default: 'sha256'\n  keyCompare?: (a: string, b: string) => number\n): string               // hex digest\n```\n\n## RFC 8785 Compliance\n\nWhen called without `replacer`, `space`, or `keyCompare`, the output conforms to [RFC 8785 (JCS)](https://www.rfc-editor.org/rfc/rfc8785):\n\n- Object keys sorted by UTF-16 code unit order\n- Numbers serialized per ES6 `Number.toString()` rules (`-0` becomes `0`)\n- Only mandatory characters escaped (`U+0000`-`U+001F`, `\"`, `\\`)\n- No whitespace\n\n## CLI\n\n```bash\n# Canonicalize\necho '{\"b\":2,\"a\":1}' | canonical-json\n# {\"a\":1,\"b\":2}\n\n# Content hash (default sha256)\necho '{\"b\":2,\"a\":1}' | canonical-json hash\n# 43258cff783fe7036d8a43033f830adfc60ec037...\n\n# Hash with specific algorithm\necho '{\"b\":2,\"a\":1}' | canonical-json hash --algo md5\n\n# Hash multiple files\ncanonical-json hash *.json\n\n# Verify files are canonical (exit 1 if not)\ncanonical-json verify data.json\ncanonical-json verify *.json\n```\n\n## Test\n\n```bash\nnpm test\n```\n\nZero dependencies. Tests use Node's built-in test runner.\n\n## License\n\nMIT\n","readmeFilename":"README.md","keywords":["json","canonical","deterministic","stringify","sorted","stable"]}