{"id":20576461,"url":"https://github.com/oyooyo/diffpatchjson","last_synced_at":"2026-05-14T13:33:35.424Z","repository":{"id":82264840,"uuid":"410537511","full_name":"oyooyo/diffpatchjson","owner":"oyooyo","description":"A small JavaScript library for diffing \u0026 patching JSON values, using low-footprint deltas/diffs","archived":false,"fork":false,"pushed_at":"2021-09-29T17:56:20.000Z","size":91,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-04-24T15:24:00.259Z","etag":null,"topics":["diff","json","patch"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oyooyo.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-26T11:49:06.000Z","updated_at":"2022-08-18T14:33:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"c1180f72-0ecf-45cb-bcc3-1ad1e4bdc84f","html_url":"https://github.com/oyooyo/diffpatchjson","commit_stats":{"total_commits":15,"total_committers":1,"mean_commits":15.0,"dds":0.0,"last_synced_commit":"4627d4c09527c7add7f1026fa84d8c2337283ab5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oyooyo%2Fdiffpatchjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oyooyo%2Fdiffpatchjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oyooyo%2Fdiffpatchjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oyooyo%2Fdiffpatchjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oyooyo","download_url":"https://codeload.github.com/oyooyo/diffpatchjson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242196397,"owners_count":20087771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diff","json","patch"],"created_at":"2024-11-16T05:45:53.304Z","updated_at":"2026-05-14T13:33:30.342Z","avatar_url":"https://github.com/oyooyo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# diffpatchjson\n\nA small JavaScript library for **diff**ing \u0026 **patch**ing **JSON** values, using low-footprint deltas/diffs.\n\n\n## Comparison with *jsondiffpatch*\n\n*diffpatchjson* is very similar to *[jsondiffpatch](https://github.com/benjamine/jsondiffpatch)*, the probably most popular JavaScript library for diffing \u0026 patching JSON values. So if you're reading this, there's a good chance that you are wondering how *diffpatchjson* compares to *jsondiffpatch* and which one you should choose.\n\nThe following sections describe some noteworthy differences between *diffpatchjson* and *jsondiffpatch*:\n\n\n### Smaller (but non-reversible) deltas/diffs\n\nThe deltas/diffs (=the data that describes the difference between the old and the new JSON value) created by *diffpatchjson* will almost always be smaller than those created by *jsondiffpatch* (after conversion to a JSON string). That's because [*jsondiffpatch*'s delta format](https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md) was developed with reversibility in mind, which basically means that it is possible to *unpatch* a *patch*ed JSON value using the same delta/diff. [*diffpatchjson*'s delta format](delta_format.md) on the other hand is not reversible, which allows for a number of optimizations that can significantly reduce the footprint of the diffs/deltas, for example:\n\n- When *jsondiffpatch* modifies a value, both the old and the new value are stored in the delta. *diffpatchjson* only stores the new value in such cases.\n- When *jsondiffpatch* changes an object, the full names/keys of the changed properties are stored in the delta as strings. *diffpatchjson* uses shorter integer indexes to identify the property, except when a new property is being added.\n\nThere is a [test page](https://oyooyo.github.io/diffpatchjson/test_page/) where you can enter two JSON values and see/compare the deltas/diffs produced by both *diffpatchjson* and *jsondiffpatch*.\n\n\n### Smaller code size, no dependencies\n\n*jsondiffpatch* depends on 8 other npm packages (2 direct + 6 indirect dependencies), and the code size (including dependencies) is about 55 kB even after minification.\n\n*diffpatchjson* on the other hand has no dependencies, and the minified code is only about 4 kB.\n\n\n### Builtin object matching\n\n*jsondiffpatch* does not automatically compare arrays/objects for equality, for example when moving arrays/objects inside an array. To overcome this limitation, the user can provide an optional `objectHash` function, but that usually requires some knowledge about the structure of the objects.\n\n*diffpatchjson* on the other hand automatically compares objects for equality by default. Since this might be computationally expensive in some cases, one can override this default behaviour:\n\n- by passing the [`compute_object_hash`](#compute_object_hash) option (this is pretty much the same as the `objectHash` option in *jsondiffpatch*)\n- by passing the [`are_objects_equal`](#are_objects_equal) option\n\n\n### No string diffs\n\nUnlike *jsondiffpatch*, *diffpatchjson* (currently?) does not have an optimized delta/diff for strings, so *jsondiffpatch* is not well suited for diffing long strings with small changes.\n\n\n### No fancy features\n\n*diffpatchjson* provides pretty much only the core functionality: `diff` \u0026 `patch` plus a few useful helper functions.\n\nIt does not provide \"output formatters\" for HTML, ANSI etc. and does not support plugins.\n\n\n## Installation\n\n```sh\nnpm install diffpatchjson\n```\n\n\n## Usage example\n\nHere's a short example that shows how to use *diffpatchjson*:\n\n```JavaScript\nimport { are_deep_equal, diff, patch } from 'diffpatchjson';\n\nlet old_value, new_value, delta, patched_value;\n\nold_value = {\n  \"name\": {\n    \"first\": \"Max\",\n    \"last\": \"Masterman\"\n  },\n  \"date of birth\": \"1984-03-23\"\n};\nnew_value = {\n  \"name\": {\n    \"first\": \"Max\",\n    \"last\": \"Mustermann\"\n  },\n  \"date of birth\": \"1984-03-23\"\n};\n\ndelta = diff(old_value, new_value);\n\nconsole.log(JSON.stringify(delta));\n// Prints: [2,[2,[\"Mustermann\"]]]\n\npatched_value = patch(old_value, delta);\n\nconsole.log(are_deep_equal(new_value, patched_value));\n// Prints: true\n```\n\n\n## API\n\nRemember to `import`:\n\n```JavaScript\nimport { are_deep_equal, deep_clone, diff, patch } from 'diffpatchjson';\n```\n\n...or `require`:\n\n```JavaScript\nconst { are_deep_equal, deep_clone, diff, patch } = require('diffpatchjson');\n```\n\n...the functions you intend to use.\n\n\n### diff\n\n```JavaScript\ndiff(old_value, new_value [, diff_options])\n```\n\nComputes and returns the delta/difference between the JSON values old_value and new_value. The returned delta/diff is a JSON value as well.\n\n#### diff options\n\n`diff` accepts an optional third object argument for passing options. Right now, the following options are supported:\n\n##### are_objects_equal\n\nIn order to check two objects for equality, you can pass a function as the `are_objects_equal` option. The function will be called with two objects as arguments, and shall return `true` if these objects are considered equal.\n\n```JavaScript\nimport { diff } from 'diffpatchjson';\n\ndiff(old_value, new_value, {\n  are_objects_equal: (object_1, object_2) = (object_1 === object_2),\n})\n```\n\nThe module exports an `are_strict_equal` function by the way that does just the above:\n\n```JavaScript\nimport { are_strict_equal, diff } from 'diffpatchjson';\n\ndiff(old_value, new_value, {\n  are_objects_equal: are_strict_equal,\n})\n```\n\n\n##### compute_object_hash\n\nAs an alternative to providing the `are_objects_equal` option, you can provide an `compute_object_hash` option. This works pretty much identical to the `objectHash` option that you may know from *jsondiffpatch*. The function will be called with an object as argument, and must return a \"hash\" value that should be the same for all objects that are considered equal.\n\nThis usually requires some knowledge about the internal structure of the objects you are diffing:\n\n```JavaScript\nimport { diff } from 'diffpatchjson';\n\ndiff(old_value, new_value, {\n  compute_object_hash: (object) = object.id,\n})\n```\n\nThe default behaviour of *diffpatchjson* by the way is that the \"hash\" of an object is simply a JSON string representation of the object:\n\n```JavaScript\nimport { diff, stringify_json_value } from 'diffpatchjson';\n\ndiff(old_value, new_value, {\n  compute_object_hash: stringify_json_value,\n})\n```\n\nThe results are being cached, so the function you pass as the `compute_object_hash` option will only be called once for each object.\n\n\n### patch\n\n```JavaScript\npatch(old_value, delta)\n```\n\nPatches old_value with a delta (created by the [`diff`](#diff) function) and returns the new/patched value.\n\n\n### are_deep_equal\n\n```JavaScript\nare_deep_equal(value_1, value_2)\n```\n\nHelper function that compares value_1 and value_2 and returns a boolean value indicating if the values are \"deep-equal\". In JavaScript, booleans, numbers, strings etc. can easily be compared for equality using the strict equality operator `===` (e.g. `\"foo\" === \"foo\"` is `true`), but objects cannot (e.g. `{a:1} === {a:1}` is `false`). The `are_deep_equal` function can help in such cases (e.g. `are_deep_equal({a:1}, {a:1})` is `true`).\n\n\n### deep_clone\n\n```JavaScript\ndeep_clone(value)\n```\n\nHelper function that returns a deep-cloned copy of the JSON value value.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foyooyo%2Fdiffpatchjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foyooyo%2Fdiffpatchjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foyooyo%2Fdiffpatchjson/lists"}