@ap-ent/diff
v1.0.0
Published
Zero-dependency TypeScript diff and patch engine
Downloads
71
Maintainers
Readme
@ap/diff
Zero-dependency TypeScript diff and patch engine. Supports line-level and character-level text diffing, deep JSON structural diffs, patch generation, patch application, and conflict detection.
Install
npm install @ap/diffUsage
Text / Line Diffing
import { diffLines, diffText, renderTextDiff } from '@ap/diff';
const lines = diffLines('Hello World', 'Hello AP');
// [{ type: 'remove', line: 'Hello World' }, { type: 'add', line: 'Hello AP' }]
const chars = diffText('abc', 'axc');
const rendered = renderTextDiff(chars);
// [{ type: 'equal', text: 'a' }, { type: 'remove', text: 'b' }, { type: 'add', text: 'x' }, { type: 'equal', text: 'c' }]JSON Diffing
import { diffJson, applyPatch, summarizePatch } from '@ap/diff';
const a = { name: 'Alice', age: 30 };
const b = { name: 'Alice', age: 31, city: 'NYC' };
const patch = diffJson(a, b);
// { operations: [{ op: 'replace', path: ['age'], oldValue: 30, value: 31 }, { op: 'add', path: ['city'], value: 'NYC' }] }
const result = applyPatch(a, patch);
// { name: 'Alice', age: 31, city: 'NYC' } — original `a` is unchanged
console.log(summarizePatch(patch));
// "1 added, 1 modified"Safe Patch Application
import { applyPatchSafe } from '@ap/diff';
const result = applyPatchSafe(modifiedOriginal, patch);
if (result.ok) {
console.log(result.result);
} else {
console.log(result.conflicts);
// [{ path: ['age'], reason: 'expected 30 but found 35' }]
}API
| Function | Description |
|---|---|
| diffText(a, b) | Character-level diff |
| diffLines(a, b) | Line-level diff |
| diffJson(a, b) | Deep JSON structural diff → JsonPatch |
| applyPatch(original, patch) | Apply patch, returns new object (never mutates) |
| canApply(original, patch) | Returns true if patch applies cleanly |
| applyPatchSafe(original, patch) | Returns { ok, result } or { ok, conflicts } |
| renderTextDiff(diff) | Convert TextDiff to DiffLine[] for rendering |
| summarizePatch(patch) | Human-readable summary string |
License
MIT © 2026 Gordon Schauer
