Ivy.NativeJsonDiff 2.0.0

dotnet add package Ivy.NativeJsonDiff --version 2.0.0
                    
NuGet\Install-Package Ivy.NativeJsonDiff -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ivy.NativeJsonDiff" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ivy.NativeJsonDiff" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Ivy.NativeJsonDiff" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ivy.NativeJsonDiff --version 2.0.0
                    
#r "nuget: Ivy.NativeJsonDiff, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ivy.NativeJsonDiff@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ivy.NativeJsonDiff&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Ivy.NativeJsonDiff&version=2.0.0
                    
Install as a Cake Tool

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.

NuGet License: MIT

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

  1. Your byte[] input is pinned and passed directly to Rust via C FFI (P/Invoke) — no managed copy
  2. Rust deserializes into serde_json::Value and runs json_patch::diff() (RFC 6902)
  3. The result is serialized to a JSON string in Rust memory
  4. .NET marshals the result back and parses it into JsonNode
  5. 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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.

Version Downloads Last Updated
2.0.0 3,266 4/12/2026
1.0.1 153 4/12/2026
1.0.0 190 4/12/2026