{"_id":"@bybrave/fast-json-patch2","name":"@bybrave/fast-json-patch2","dist-tags":{"latest":"4.0.0"},"versions":{"4.0.0":{"name":"@bybrave/fast-json-patch2","version":"4.0.0","description":"Maintained fork of fast-json-patch — RFC-6902 JSON Patch with observe/compare, now with a modern exports map, dual ESM+CJS, built-in types, a Date/toJSON compare fix and 0 dependencies","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"build":"tsup","prepublishOnly":"npm run build","test":"npm run build && node --test test/*.test.js","test-types":"tsc --noEmit --strict test/type-declarations.ts"},"repository":{"type":"git","url":"git+https://github.com/bybraveHQ/fast-json-patch2.git"},"bugs":{"url":"https://github.com/bybraveHQ/fast-json-patch2/issues"},"homepage":"https://github.com/bybraveHQ/fast-json-patch2#readme","keywords":["json","patch","json-patch","rfc6902","rfc-6902","json-pointer","diff","observe","compare","typescript","esm"],"author":{"name":"bybrave","url":"https://github.com/bybraveHQ"},"contributors":[{"name":"Joachim Wester","url":"author of the original fast-json-patch"}],"license":"MIT","funding":"https://ko-fi.com/bybrave","engines":{"node":">=18"},"devDependencies":{"@types/node":"^20.14.0","tsup":"^8.0.0","typescript":"^5.5.0"},"_id":"@bybrave/fast-json-patch2@4.0.0","gitHead":"f1a99cc00df57455ee68f26c33cc2542edc696a1","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-DoXFXew7HujhWaYMuPY/Z3ih+PysJhNxzAgsVRMKGLMEq/j/N7DuxvHMZgyND9D20khbgnHLWWhi1CiW7dyuZQ==","shasum":"f97ec5e890736374d0fef14d85648bccd12aec39","tarball":"https://registry.npmjs.org/@bybrave/fast-json-patch2/-/fast-json-patch2-4.0.0.tgz","fileCount":7,"unpackedSize":72039,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDTAQU6Q+005MxDbsL2uwOiYcPEI3MFKqqvgynrZbJR9QIgdgzPdwdIY8WNig71cNlyBYpslBLdrihl9IZntYpFzdg="}]},"_npmUser":{"name":"bybrave","email":"opmybrave@gmail.com"},"directories":{},"maintainers":[{"name":"bybrave","email":"opmybrave@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fast-json-patch2_4.0.0_1783470101614_0.8237441265656957"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-08T00:21:41.393Z","4.0.0":"2026-07-08T00:21:41.758Z","modified":"2026-07-08T00:21:41.957Z"},"maintainers":[{"name":"bybrave","email":"opmybrave@gmail.com"}],"description":"Maintained fork of fast-json-patch — RFC-6902 JSON Patch with observe/compare, now with a modern exports map, dual ESM+CJS, built-in types, a Date/toJSON compare fix and 0 dependencies","homepage":"https://github.com/bybraveHQ/fast-json-patch2#readme","keywords":["json","patch","json-patch","rfc6902","rfc-6902","json-pointer","diff","observe","compare","typescript","esm"],"repository":{"type":"git","url":"git+https://github.com/bybraveHQ/fast-json-patch2.git"},"contributors":[{"name":"Joachim Wester","url":"author of the original fast-json-patch"}],"author":{"name":"bybrave","url":"https://github.com/bybraveHQ"},"bugs":{"url":"https://github.com/bybraveHQ/fast-json-patch2/issues"},"license":"MIT","readme":"# @bybrave/fast-json-patch2\n\n[![CI](https://github.com/bybraveHQ/fast-json-patch2/actions/workflows/ci.yml/badge.svg)](https://github.com/bybraveHQ/fast-json-patch2/actions)\n[![npm](https://img.shields.io/npm/v/%40bybrave%2Ffast-json-patch2)](https://www.npmjs.com/package/@bybrave/fast-json-patch2)\n\nMaintained fork of [`fast-json-patch`](https://github.com/Starcounter-Jack/JSON-Patch) — a fast [RFC-6902](https://tools.ietf.org/html/rfc6902) JSON-Patch implementation with observe/compare (diff) support — with a **modern `exports` map**, **dual ESM+CJS**, **built-in TypeScript types**, a **`Date`/`toJSON` compare fix** and **0 dependencies**.\n\nThe original package has ~30M downloads/month and no release since 2022. Its `package.json` has no `exports` field (so named ESM imports and modern bundlers break) and `compare`/`observe` shred `Date` values into char-by-char patches. This fork keeps the RFC-6902 apply path byte-for-byte (verified against the official JSON-Patch conformance suite) and fixes the packaging and diff bugs.\n\n```bash\nnpm install @bybrave/fast-json-patch2\n```\n\n```js\n// CommonJS\nconst jsonpatch = require('@bybrave/fast-json-patch2');\n\n// ESM — named imports now work\nimport { applyPatch, compare, observe, generate } from '@bybrave/fast-json-patch2';\n\n// TypeScript types built in\n```\n\n## The Date bug, and how it is fixed\n\n`compare` and `observe` clone the document through `JSON.stringify`, which turns a `Date` into an ISO string. The live object still holds the `Date`, so the diff walks a string against an object and emits one `add` per character:\n\n```js\n// original fast-json-patch@3.1.1\ncompare({ when: new Date('2024-01-01') }, { when: new Date('2024-06-15') });\n// [ {op:'add', path:'/when/0', value:'2'}, {op:'add', path:'/when/1', value:'0'}, … ] 💥\n```\n\n**This fork** treats any value exposing `toJSON` (`Date`, luxon `DateTime`, Decimal.js, …) as an atomic leaf and diffs it by its serialized form:\n\n```js\n// @bybrave/fast-json-patch2\ncompare({ when: new Date('2024-01-01') }, { when: new Date('2024-06-15') });\n// [ { op: 'replace', path: '/when', value: '2024-06-15T00:00:00.000Z' } ]\n\ncompare({ t: new Date('2024-01-01') }, { t: new Date('2024-01-01') });\n// []  — equal dates, no spurious patch\n```\n\nThe apply path is untouched, so this changes nothing about how patches are applied — only how `compare`/`observe` generate them.\n\n## Fixes over `fast-json-patch@3.1.1`\n\n| Fixed | Original issue |\n|---|---|\n| No `exports` map → named ESM imports and bundlers (parcel, webpack 5) fail | [#310](https://github.com/Starcounter-Jack/JSON-Patch/issues/310), [#317](https://github.com/Starcounter-Jack/JSON-Patch/issues/317), [#311](https://github.com/Starcounter-Jack/JSON-Patch/issues/311), [#129](https://github.com/Starcounter-Jack/JSON-Patch/issues/129), [#323](https://github.com/Starcounter-Jack/JSON-Patch/issues/323) |\n| `compare`/`observe` shred `Date` / `toJSON` values into char-by-char patches | [#325](https://github.com/Starcounter-Jack/JSON-Patch/issues/325), [#272](https://github.com/Starcounter-Jack/JSON-Patch/issues/272), [#278](https://github.com/Starcounter-Jack/JSON-Patch/issues/278), [#318](https://github.com/Starcounter-Jack/JSON-Patch/issues/318), [#332](https://github.com/Starcounter-Jack/JSON-Patch/issues/332), [#183](https://github.com/Starcounter-Jack/JSON-Patch/issues/183) |\n| ESM delivered via a `sed`-based build script | — (replaced with tsup) |\n| Empty-string key (`\"\"`) round-trip, `undefined`-source diff — regression-tested | [#260](https://github.com/Starcounter-Jack/JSON-Patch/issues/260), [#280](https://github.com/Starcounter-Jack/JSON-Patch/issues/280) |\n| `escapePathComponent` / `unescapePathComponent` public and typed | [#173](https://github.com/Starcounter-Jack/JSON-Patch/issues/173) |\n\n### By design (documented, not changed)\n\n- `compare` is a **positional** array diff — inserting into an array can produce a cascade of `replace` ops. The patch is valid and applies correctly; minimal (LCS) array diffing is out of scope ([#215](https://github.com/Starcounter-Jack/JSON-Patch/issues/215), [#282](https://github.com/Starcounter-Jack/JSON-Patch/issues/282)).\n- No `move` generation in `compare` ([#91](https://github.com/Starcounter-Jack/JSON-Patch/issues/91)); `observe` keeps dirty-checking, not Proxy ([#96](https://github.com/Starcounter-Jack/JSON-Patch/issues/96)).\n- The RFC-6902 operation logic, JSON-Pointer handling and the `banPrototypeModifications` security guard are preserved exactly.\n\n## Migrating from fast-json-patch\n\n```diff\n- const jsonpatch = require('fast-json-patch');\n+ const jsonpatch = require('@bybrave/fast-json-patch2');\n```\n\nThe API is identical. Named ESM imports that used to fail now work:\n\n```js\nimport { applyPatch, compare } from '@bybrave/fast-json-patch2';\n```\n\nIf you diff documents containing `Date` values, `compare`/`observe` now produce clean `replace` ops instead of char-by-char patches — no code change needed on your side.\n\n## API\n\n```js\n// Apply\njsonpatch.applyPatch(document, patch);                 // returns { newDocument, … }\njsonpatch.applyOperation(document, operation);\njsonpatch.applyReducer(document, operation, index);    // reducer signature\njsonpatch.getValueByPointer(document, '/a/b');\n\n// Validate\njsonpatch.validate(patch, document?);                  // returns JsonPatchError | undefined\n\n// Diff & observe\njsonpatch.compare(objA, objB);                         // Operation[]\nconst observer = jsonpatch.observe(document);\njsonpatch.generate(observer);                          // Operation[] since last generate\njsonpatch.unobserve(document, observer);\n\n// JSON-Pointer helpers\njsonpatch.escapePathComponent('a/b');                  // 'a~1b'\njsonpatch.unescapePathComponent('a~1b');               // 'a/b'\n```\n\n## Support\n\nIf this package saves you time, you can support maintenance:\n\n[![Ko-fi](https://img.shields.io/badge/Ko--fi-buy%20me%20a%20coffee-FF5E5B?logo=kofi&logoColor=white)](https://ko-fi.com/bybrave)\n[![Bitcoin](https://img.shields.io/badge/Bitcoin-BTC-F7931A?logo=bitcoin&logoColor=white)](#support)\n\nBitcoin (BTC): `bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q`\n\n## Credits & license\n\nMIT. Based on [fast-json-patch](https://github.com/Starcounter-Jack/JSON-Patch) by Joachim Wester.\n","readmeFilename":"README.md","_rev":"1-2effd93bb011750da52ceed685ffdebf"}