{"id":51119043,"url":"https://github.com/sulthonzh/jsonpatch","last_synced_at":"2026-06-25T00:30:39.731Z","repository":{"id":365065341,"uuid":"1268586042","full_name":"sulthonzh/jsonpatch","owner":"sulthonzh","description":"RFC 6902 JSON Patch — apply, diff, and validate patches with zero dependencies","archived":false,"fork":false,"pushed_at":"2026-06-15T17:29:07.000Z","size":10,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-15T19:22:02.882Z","etag":null,"topics":["diff","json","json-patch","merge","patch","rfc6902"],"latest_commit_sha":null,"homepage":null,"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/sulthonzh.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-13T17:51:13.000Z","updated_at":"2026-06-15T17:19:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sulthonzh/jsonpatch","commit_stats":null,"previous_names":["sulthonzh/jsonpatch"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/sulthonzh/jsonpatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fjsonpatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fjsonpatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fjsonpatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fjsonpatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sulthonzh","download_url":"https://codeload.github.com/sulthonzh/jsonpatch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fjsonpatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34755061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","json-patch","merge","patch","rfc6902"],"created_at":"2026-06-25T00:30:39.556Z","updated_at":"2026-06-25T00:30:39.722Z","avatar_url":"https://github.com/sulthonzh.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @sulthonzh/jsonpatch\n\n\u003e RFC 6902 JSON Patch — apply, diff, and validate patches with zero dependencies\n\nJSON Patch is a standard way to describe changes to a JSON document. This library implements the full spec: all 6 operations (`add`, `remove`, `replace`, `move`, `copy`, `test`), JSON Pointer (RFC 6901) navigation, and a diff engine that generates patches between any two values.\n\n## Why\n\nYou need to track what changed between two versions of a JSON document — for audit logs, collaborative editing, state synchronization, or API PATCH endpoints. This library handles both directions: apply patches and generate them.\n\n## Install\n\n```bash\nnpm install @sulthonzh/jsonpatch\n```\n\n## Quick Start\n\n```js\nconst { applyPatch, diff, validate } = require('@sulthonzh/jsonpatch');\n\n// Apply a patch\nconst doc = { name: 'Alice', age: 30 };\nconst result = applyPatch(doc, [\n  { op: 'replace', path: '/age', value: 31 },\n  { op: 'add', path: '/email', value: 'alice@example.com' },\n]);\n// → { name: 'Alice', age: 31, email: 'alice@example.com' }\n\n// Generate a patch between two documents\nconst patch = diff(\n  { name: 'Alice', age: 30 },\n  { name: 'Bob', age: 30 }\n);\n// → [{ op: 'replace', path: '/name', value: 'Bob' }]\n\n// Validate before applying\nconst check = validate([{ op: 'add', path: '/x', value: 1 }]);\n// → { valid: true }\n```\n\n## API\n\n### `applyPatch(doc, patch, opts?)`\n\nApplies a JSON Patch array to a document. Returns a **new** document (original is not mutated unless `opts.mutate` is `true`).\n\n```js\nconst result = applyPatch(doc, [\n  { op: 'add', path: '/tags/-', value: 'new' },     // append to array\n  { op: 'remove', path: '/temp' },                   // delete property\n  { op: 'move', from: '/oldName', path: '/newName' },\n  { op: 'copy', from: '/source', path: '/backup' },\n  { op: 'test', path: '/version', value: 1 },        // assertion — throws if mismatch\n]);\n```\n\n### `diff(a, b)`\n\nGenerates a minimal patch that transforms `a` into `b`. Uses prefix/suffix matching for arrays and key-level diffing for objects.\n\n```js\nconst patch = diff(\n  { users: [{ id: 1, name: 'Alice' }] },\n  { users: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }] }\n);\n// → [{ op: 'add', path: '/users/1', value: { id: 2, name: 'Bob' } }]\n```\n\nRoundtrip guarantee: `applyPatch(a, diff(a, b))` always equals `b`.\n\n### `validate(patch)`\n\nChecks structural validity without applying. Returns `{ valid: true }` or `{ valid: false, error: string, index?: number }`.\n\n### `pointer.parse(ptr)` / `pointer.serialize(tokens)`\n\nJSON Pointer (RFC 6901) utilities.\n\n```js\npointer.parse('/foo/0/bar');  // → ['foo', '0', 'bar']\npointer.serialize(['a', 'b/c~d']);  // → '/a/b~1c~0d'\n```\n\n## All Operations\n\n| Op | Description | Example |\n|----|-------------|---------|\n| `add` | Insert value at path (creates or overwrites) | `{ op: 'add', path: '/b', value: 2 }` |\n| `remove` | Delete value at path | `{ op: 'remove', path: '/a' }` |\n| `replace` | Replace value at path | `{ op: 'replace', path: '/a', value: 99 }` |\n| `move` | Move value from one path to another | `{ op: 'move', from: '/a', path: '/b' }` |\n| `copy` | Copy value from one path to another | `{ op: 'copy', from: '/a', path: '/b' }` |\n| `test` | Assert path equals value (throws if not) | `{ op: 'test', path: '/v', value: 1 }` |\n\n### Special paths\n\n- `\"\"` (empty string) → document root\n- `\"-\"` in arrays → append (e.g., `\"/items/-\"`)\n- `\"/0\"`, `\"/1\"` → array indices\n\n### Escaping\n\n`~` is `~0` and `/` is `~1` in JSON Pointers (RFC 6901).\n\n```js\n// Key \"a/b\" → pointer \"/a~1b\"\n{ op: 'add', path: '/a~1b', value: 1 }\n```\n\n## CLI\n\n```bash\n# Apply a patch\njsonpatch apply doc.json patch.json\n\n# Generate a diff\njsonpatch diff old.json new.json\n\n# Validate a patch file\njsonpatch validate patch.json\n\n# From stdin\ncat doc.json | jsonpatch apply - patch.json --compact\n```\n\n## Design Choices\n\n- **Zero dependencies.** No transitive bloat.\n- **Immutable by default.** `applyPatch` returns a new document. Pass `{ mutate: true }` to avoid the clone cost.\n- **Roundtrip-safe diff.** `diff(a, b)` then `applyPatch(a, ...)` always produces `b`.\n- **Strict validation.** Leading zeros in array indices are rejected (RFC 6902 §4.1). Out-of-bounds indices throw.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsulthonzh%2Fjsonpatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsulthonzh%2Fjsonpatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsulthonzh%2Fjsonpatch/lists"}