jsondiffpatch
Diff & patch JavaScript objects
- min+gzipped < 6KB
- browser (
/public/build/jsondiffpatch.js
) and server (eg. node.js) - includes google-diff-match-patch for long text diffs (diff at character level)
- smart array diffing using LCS, IMPORTANT NOTE: to match objects inside an array you must provide an
objectHash
function (this is how objects are matched, otherwise a dumb match by position is used). For more details, check Array diff documentation - reverse a delta
- unpatch (eg. revert object to its original state using a delta)
- simplistic, pure JSON, low footprint delta format
- multiple output formatters:
- html (check it at the Live Demo)
- annotated json (html), makes the JSON delta format self-explained
- console (colored), try running
./node_modules/.bin/jsondiffpatch left.json right.json
- write your own! check Formatters documentation
Supported platforms
- Any modern browser and IE8+
And you can test your current browser visiting the test page.
- Node.js
If you want to run tests locally:
npm i
npm test
BROWSERS=chrome,phantomjs npm test
Usage
var country = {
name: "Argentina",
capital: "Buenos Aires",
independence: new Date(1816, 6, 9),
unasur: true
};
var country2 = JSON.parse(JSON.stringify(country), jsondiffpatch.dateReviver);
country2.name = "Republica Argentina";
country2.population = 41324992;
delete country2.capital;
var delta = jsondiffpatch.diff(country, country2);
assertSame(delta, {
"name":["Argentina","Republica Argentina"],
"population":["41324992"],
"capital":["Buenos Aires", 0, 0]
});
jsondiffpatch.patch(country, delta);
var reverseDelta = jsondiffpatch.reverse(delta);
var delta2 = jsondiffpatch.diff(country, country2);
assert(delta2 === undefined)
Array diffing:
var country = {
name: "Argentina",
cities: [
{
name: 'Buenos Aires',
population: 13028000,
},
{
name: 'Cordoba',
population: 1430023,
},
{
name: 'Rosario',
population: 1136286,
},
{
name: 'Mendoza',
population: 901126,
},
{
name: 'San Miguel de Tucuman',
population: 800000,
}
]
};
var country2 = JSON.parse(JSON.stringify(country));
country.cities.splice(1, 1);
country.cities.splice(4, 0, {
name: 'La Plata'
});
var rosario = country.cities.splice(1, 1)[0];
rosario.population += 1234;
country.cities.push(rosario);
var diffpatcher = jsondiffpatch.create({
objectHash: function(obj) {
return obj.name;
}
});
var delta = diffpatcher.diff(country, country2);
assertSame(delta, {
"cities": {
"_t": "a",
"1": [
{
"name": "Cordoba",
"population": 1430023
}]
,
"2": {
"population": [
1137520,
1136286
]
},
"_3": [
{
"name": "La Plata"
}, 0, 0],
"_4": [
'', 2, 3]
}
});
For more example cases (nested objects or arrays, long text diffs) check test/examples/
If you want to understand deltas, see delta format documentation
Installing
npm (node.js)
npm install jsondiffpatch
var jsondiffpatch = require('jsondiffpatch').create(options);
bower (browser)
bower install jsondiffpatch
browser bundles are in the /public/build
folder (you can re-generate these using make
or gulp
, npm test
will do that too):
jsondiffpatch.js
main bundlejsondiffpatch.full.js
main bundle + google-diff-match-patch library for text diffsjsondiffpatch-formatters.js
builtin formatters (only those useful in a browser)
All these come in minified versions (.min.js
), and separate sourcemap files.
Options
var jsondiffpatch = require('jsondiffpatch').create({
objectHash: function(obj) {
return obj._id || obj.id;
},
arrays: {
detectMove: true,
includeValueOnMove: false
},
textDiff: {
minLength: 60
},
propertyFilter: function(name, context) {
return name.slice(0, 1) !== '$';
},
cloneDiffValues: false
});
Visual Diff
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="public/build/jsondiffpatch.min.js"></script>
<script type="text/javascript" src="public/build/jsondiffpatch-formatters.min.js"></script>
<link rel="stylesheet" href="public/formatters-styles/html.css" type="text/css" />
<link rel="stylesheet" href="public/formatters-styles/annotated.css" type="text/css" />
</head>
<body>
<div id="visual"></div>
<hr/>
<div id="annotated"></div>
<script>
var left = { a: 3, b: 4 };
var right = { a: 5, c: 9 };
var delta = jsondiffpatch.diff(left, right);
document.getElementById('visual').innerHTML = jsondiffpatch.formatters.html.format(delta, left);
document.getElementById('annotated').innerHTML = jsondiffpatch.formatters.annotated.format(delta, left);
</script>
</body>
</html>
To see formatters in action check the Live Demo.
For more details check Formatters documentation
Console
./node_modules/.bin/jsondiffpatch ./left.json ./right.json
npm install -g jsondiffpatch
jsondiffpatch ./demo/left.json ./demo/right.json
Plugins
diff()
, patch()
and reverse()
functions are implemented using Pipes & Filters pattern, making it extremely customizable by adding or replacing filters on a pipe.
Check Plugins documentation for details.