Ivy.NativeJsonDiff
2.0.0
dotnet add package Ivy.NativeJsonDiff --version 2.0.0
NuGet\Install-Package Ivy.NativeJsonDiff -Version 2.0.0
<PackageReference Include="Ivy.NativeJsonDiff" Version="2.0.0" />
<PackageVersion Include="Ivy.NativeJsonDiff" Version="2.0.0" />
<PackageReference Include="Ivy.NativeJsonDiff" />
paket add Ivy.NativeJsonDiff --version 2.0.0
#r "nuget: Ivy.NativeJsonDiff, 2.0.0"
#:package Ivy.NativeJsonDiff@2.0.0
#addin nuget:?package=Ivy.NativeJsonDiff&version=2.0.0
#tool nuget:?package=Ivy.NativeJsonDiff&version=2.0.0
Ivy.NativeJsonDiff
The fastest JSON diff and patch library for .NET — powered by native Rust.
A high-performance, zero-overhead alternative to JsonDiffPatch.Net, SystemTextJson.JsonDiffPatch, and JsonPatch.Net. Computes RFC 6902 JSON Patch diffs at native speed via Rust FFI.
Why NativeJsonDiff?
Most .NET JSON diff libraries run entirely in managed code — parsing JSON trees, walking nodes, allocating intermediate objects, and producing diffs in the GC-managed heap. Ivy.NativeJsonDiff takes a fundamentally different approach: the entire diff and patch computation runs in native Rust, where there is no garbage collector, no boxing, and no allocation overhead.
| Ivy.NativeJsonDiff | JsonDiffPatch.Net | SystemTextJson.JsonDiffPatch | JsonPatch.Net | |
|---|---|---|---|---|
| Engine | Native Rust FFI | Managed (.NET) | Managed (.NET) | Managed (.NET) |
| JSON library | System.Text.Json | Newtonsoft.Json | System.Text.Json | System.Text.Json |
| RFC 6902 | Yes | No (custom format) | Optional | Yes |
| Patch apply | Yes | Yes | Yes | Yes |
| Allocations | Minimal (FFI boundary only) | High (JToken graph) | Medium (JsonNode graph) | Medium (JsonNode graph) |
| Platforms | win/linux/osx, x64/arm64 | Any | Any | Any |
Performance
NativeJsonDiff is benchmarked against every major .NET JSON diff library using BenchmarkDotNet across 9 payload categories (Small, Medium, Large, DeepNested, ArrayHeavy, ApiResponse, ConfigFile, LargeStateTree, VeryLargeStateTree — up to 2MB JSON trees).
Run benchmarks yourself:
cd src/Ivy.NativeJsonDiff.Benchmarks
dotnet run -c Release
Three benchmark suites are included:
- End-to-End Diff — raw JSON string in, parsed patch out (the real-world scenario)
- Pre-Parsed Diff — competitors get pre-parsed DOM objects; NativeJsonDiff still takes raw bytes
- Patch Apply — apply a pre-computed patch to a document
Benchmarks run on every release. Results are published as GitHub Actions artifacts on the Releases page.
Installation
dotnet add package Ivy.NativeJsonDiff
Works out of the box on:
- Windows x64/ARM64
- Linux x64/ARM64 (glibc and musl/Alpine)
- macOS x64/ARM64 (Intel and Apple Silicon)
No native toolchain required — pre-compiled Rust binaries are bundled in the NuGet package.
Quick Start
Compute a JSON diff (RFC 6902 JSON Patch)
using System.Text;
using System.Text.Json.Nodes;
using Ivy.NativeJsonDiff;
var oldJson = Encoding.UTF8.GetBytes("""
{
"name": "Alice",
"age": 30,
"roles": ["admin", "user"]
}
""");
var newJson = Encoding.UTF8.GetBytes("""
{
"name": "Alice",
"age": 31,
"roles": ["admin", "user", "moderator"]
}
""");
JsonNode? patch = JsonDiffer.ComputePatch(oldJson, newJson);
Console.WriteLine(patch);
// [
// {"op":"replace","path":"/age","value":31},
// {"op":"add","path":"/roles/2","value":"moderator"}
// ]
Apply a JSON patch
var document = Encoding.UTF8.GetBytes("""{"name":"Alice","age":30}""");
var patch = Encoding.UTF8.GetBytes("""[{"op":"replace","path":"/age","value":31}]""");
JsonNode? result = JsonDiffer.ApplyPatch(document, patch);
Console.WriteLine(result);
// {"name":"Alice","age":31}
API Reference
public static class JsonDiffer
{
// Compute RFC 6902 JSON Patch diff between two JSON documents
static JsonNode? ComputePatch(byte[] oldTreeBytes, byte[] newTreeBytes);
// Apply an RFC 6902 JSON Patch to a JSON document
static JsonNode? ApplyPatch(byte[] jsonBytes, byte[] patchBytes);
}
Both methods accept UTF-8 encoded JSON as byte[] and return System.Text.Json.Nodes.JsonNode?. Returns null for identical documents or invalid input.
How It Works
- Your
byte[]input is pinned and passed directly to Rust via C FFI (P/Invoke) — no managed copy - Rust deserializes into
serde_json::Valueand runsjson_patch::diff()(RFC 6902) - The result is serialized to a JSON string in Rust memory
- .NET marshals the result back and parses it into
JsonNode - Rust memory is freed immediately — no leaks, no finalizers
The native library is stateless — no background processes, no server, no shared memory. Pure function calls.
Migrating from Other Libraries
From JsonDiffPatch.Net
// Before (JsonDiffPatch.Net + Newtonsoft.Json)
var jdp = new JsonDiffPatch();
JToken diff = jdp.Diff(JToken.Parse(oldJson), JToken.Parse(newJson));
// After (Ivy.NativeJsonDiff + System.Text.Json)
JsonNode? patch = JsonDiffer.ComputePatch(
Encoding.UTF8.GetBytes(oldJson),
Encoding.UTF8.GetBytes(newJson));
From SystemTextJson.JsonDiffPatch
// Before
JsonNode diff = JsonNode.Parse(oldJson).Diff(JsonNode.Parse(newJson));
// After
JsonNode? patch = JsonDiffer.ComputePatch(
Encoding.UTF8.GetBytes(oldJson),
Encoding.UTF8.GetBytes(newJson));
From JsonPatch.Net
// Before
JsonPatch patch = JsonNode.Parse(oldJson).CreatePatch(JsonNode.Parse(newJson));
// After (same RFC 6902 format, much faster)
JsonNode? patch = JsonDiffer.ComputePatch(
Encoding.UTF8.GetBytes(oldJson),
Encoding.UTF8.GetBytes(newJson));
Use Cases
- Real-time collaboration — diff and sync JSON state between clients
- Audit logging — generate RFC 6902 patches for every state change
- API versioning — compute diffs between API response versions
- Configuration management — track and apply config changes as patches
- State synchronization — efficient state transfer in distributed systems
- Database change tracking — diff JSON columns and store compact patches
- Testing — compare expected vs actual JSON output with structural diffs
Building from Source
Prerequisites
- .NET 10.0 SDK
- Rust toolchain (stable)
Build
cd src/RustServer && cargo build --release
cd ../Ivy.NativeJsonDiff && dotnet build
Run Tests
dotnet test
Run Benchmarks
cd src/Ivy.NativeJsonDiff.Benchmarks
dotnet run -c Release
License
MIT — see LICENSE
Keywords
json diff, json patch, json compare, RFC 6902, json merge patch, json diff dotnet, json patch dotnet, json diff csharp, json patch csharp, system.text.json diff, system.text.json patch, newtonsoft json diff, json diff performance, json diff benchmark, native json diff, rust json diff, fast json diff, json structural diff, json deep compare, json delta, json changeset, jsondiffpatch alternative, JsonDiffPatch.Net alternative, SystemTextJson.JsonDiffPatch alternative, JsonPatch.Net alternative
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Ivy.NativeJsonDiff:
| Package | Downloads |
|---|---|
|
Ivy
Build Internal Applications with AI and Pure C# |
GitHub repositories
This package is not used by any popular GitHub repositories.