Philiprehberger.JsonPatch 0.2.1

dotnet add package Philiprehberger.JsonPatch --version 0.2.1
                    
NuGet\Install-Package Philiprehberger.JsonPatch -Version 0.2.1
                    
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="Philiprehberger.JsonPatch" Version="0.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Philiprehberger.JsonPatch" Version="0.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Philiprehberger.JsonPatch" />
                    
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 Philiprehberger.JsonPatch --version 0.2.1
                    
#r "nuget: Philiprehberger.JsonPatch, 0.2.1"
                    
#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 Philiprehberger.JsonPatch@0.2.1
                    
#: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=Philiprehberger.JsonPatch&version=0.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Philiprehberger.JsonPatch&version=0.2.1
                    
Install as a Cake Tool

Philiprehberger.JsonPatch

CI NuGet Last updated

RFC 6902 JSON Patch operations for System.Text.Json — apply, generate, and parse patch documents.

Installation

dotnet add package Philiprehberger.JsonPatch

Usage

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var document = JsonNode.Parse("""{"name": "Alice", "age": 30}""");

var operations = new[]
{
    PatchOperation.Replace("/name", JsonValue.Create("Bob")),
    PatchOperation.Add("/email", JsonValue.Create("bob@example.com")),
    PatchOperation.Remove("/age")
};

var result = JsonPatch.Apply(document, operations);
// {"name":"Bob","email":"bob@example.com"}

Generate a Diff

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var before = JsonNode.Parse("""{"name": "Alice", "age": 30}""");
var after = JsonNode.Parse("""{"name": "Alice", "age": 31, "email": "alice@example.com"}""");

var operations = JsonPatch.Diff(before, after);

foreach (var op in operations)
    Console.WriteLine($"{op.Op} {op.Path}");
// replace /age
// add /email

Parse from JSON

using Philiprehberger.JsonPatch;

var json = """
[
  { "op": "replace", "path": "/name", "value": "Bob" },
  { "op": "remove", "path": "/age" }
]
""";

var patchDoc = JsonPatch.Parse(json);
var result = patchDoc.Apply(JsonNode.Parse("""{"name": "Alice", "age": 30}"""));
// {"name":"Bob"}

Reverse Patch Generation

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var original = JsonNode.Parse("""{"name": "Alice", "age": 30}""");
var patch = new JsonPatchDocument(new[]
{
    PatchOperation.Replace("/name", JsonValue.Create("Bob")),
    PatchOperation.Remove("/age")
});

var patched = patch.Apply(original);
var reverse = JsonPatch.GenerateReverse(patch, JsonNode.Parse("""{"name": "Alice", "age": 30}"""));
var restored = reverse.Apply(patched);
// restored = {"name":"Alice","age":30}

Patch Validation

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var document = JsonNode.Parse("""{"name": "Alice"}""");
var patch = new JsonPatchDocument(new[]
{
    PatchOperation.Remove("/nonexistent")
});

var result = JsonPatch.Validate(patch, document);
// result.IsValid == false
// result.Errors[0].Message contains "does not exist"

Patch Composition

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var first = new JsonPatchDocument(new[]
{
    PatchOperation.Replace("/name", JsonValue.Create("Bob"))
});
var second = new JsonPatchDocument(new[]
{
    PatchOperation.Add("/email", JsonValue.Create("bob@example.com"))
});

var composed = JsonPatch.Compose(first, second);
var result = composed.Apply(JsonNode.Parse("""{"name": "Alice"}"""));
// {"name":"Bob","email":"bob@example.com"}

Partial Application

using System.Text.Json.Nodes;
using Philiprehberger.JsonPatch;

var document = JsonNode.Parse("""{"name": "Alice"}""");
var patch = new JsonPatchDocument(new[]
{
    PatchOperation.Replace("/name", JsonValue.Create("Bob")),
    PatchOperation.Remove("/nonexistent"),
    PatchOperation.Add("/age", JsonValue.Create(30))
});

var result = JsonPatch.ApplyPartial(patch, document);
// result.IsFullyApplied == false
// result.Applied.Count == 2
// result.Failures.Count == 1
// result.Document = {"name":"Bob","age":30}

API

JsonPatch

Method Description
Apply(JsonNode?, IEnumerable<PatchOperation>) Apply patch operations to a document, returning a modified copy
Diff(JsonNode?, JsonNode?) Generate patch operations that transform one document into another
Parse(string) Parse a JSON array of RFC 6902 operations into a JsonPatchDocument
GenerateReverse(JsonPatchDocument, JsonNode?) Generate a reverse patch that undoes the given forward patch
Validate(JsonPatchDocument, JsonNode?) Pre-check whether a patch can be cleanly applied to a document
Compose(JsonPatchDocument, JsonPatchDocument) Merge two patches into a single equivalent patch
ApplyPartial(JsonPatchDocument, JsonNode?) Apply operations individually, collecting successes and failures

JsonPatchDocument

Member Description
JsonPatchDocument(IEnumerable<PatchOperation>) Create a patch document from a sequence of operations
Operations Read-only list of patch operations
Apply(JsonNode?) Apply all operations to a document copy

PatchOperation

Member Description
Op Operation type (add, remove, replace, move, copy, test)
Path Target JSON Pointer path
From Source path for move/copy operations
Value Value for add/replace/test operations
Add(string, JsonNode?) Create an add operation
Remove(string) Create a remove operation
Replace(string, JsonNode?) Create a replace operation
Move(string, string) Create a move operation
Copy(string, string) Create a copy operation
Test(string, JsonNode?) Create a test operation

ValidationResult

Member Description
IsValid Whether the patch can be cleanly applied without errors
Errors List of validation errors encountered

ValidationError

Member Description
Operation The patch operation that failed validation
Message Description of why the operation would fail

PartialApplicationResult

Member Description
Document The document after applying all successful operations
Applied Operations that were successfully applied
Failures Operations that failed with their error messages
IsFullyApplied Whether all operations were successfully applied

OperationFailure

Member Description
Operation The patch operation that failed
Error Error message describing why the operation failed

Development

dotnet build src/Philiprehberger.JsonPatch.csproj --configuration Release

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 127 4/1/2026
0.2.0 170 3/28/2026
0.1.1 112 3/23/2026
0.1.0 106 3/21/2026