Skip to content
CAI
Software that uses CAICheck a score

gnieh/diffson

62.3

Adequate · 20 September 2026

2.8k

lines of production code

Scala

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

Diffson is a Scala library that computes differences between JSON documents and applies JSON Patch (RFC 6902) and JSON Merge Patch (RFC 7396) operations. It provides a modular, type-class-based architecture that supports multiple JSON libraries, including Circe, Play JSON, spray-json, and ujson. The system implements configurable diffing strategies, such as Longest Common Subsequence and Patience algorithms, to handle array and object changes efficiently.

How it got here

2013–2016 — Modernization and multi-library support

5 changes.

The project underwent a significant architectural overhaul, migrating the build infrastructure to sbt 1.x and adopting the Typelevel ecosystem. This period saw the removal of legacy Lift-json dependencies in favor of a Cats-based API that supports multiple JSON libraries and modern Scala versions.

2019–2023 — Type-class refactoring and multi-format support

15 changes.

The core library was refactored to a type-class based architecture, introducing configurable diffing strategies and JSON Merge Patch support alongside RFC 6901 compliant JSON Pointer navigation. New integration modules were added for spray-json, ujson, and Play JSON, while comprehensive conformance tests and benchmarks were implemented to validate correctness and performance across all formats.

Features

Add Play JSON integration for JSON Patch and Merge Patch

This change introduces a new Play JSON module that enables the library to serialize and deserialize JSON Patch and JSON Merge Patch operations using Play's JsValue type. It provides the necessary implicit Formats for Pointer, Operation, JsonPatch, and JsonMergePatch, along with a Jsony instance to bridge the core diffing logic with Play's JSON representation, allowing users to apply patches directly to Play JSON objects.

playJson/shared · high confidence

Add ujson integration for JSON Patch and Merge Patch

This change introduces a new integration module for the ujson library, enabling Diffson to work with ujson's \Value\ type. The \package.scala\ file provides the necessary \Jsony\, \Writer\, and \Reader\ instances to serialize and deserialize JSON Patch and JSON Merge Patch operations using ujson, while \FieldMissing.scala\ defines a specific exception for missing fields during decoding. Comprehensive test suites are included to verify JSON Pointer, JSON Patch, and JSON Merge Patch functionality with ujson.

circe/shared/src/main, ujson/shared · high confidence

Added spray-json integration for JSON Patch and Merge Patch operations

This change introduces a new integration module for the spray-json library, enabling Diffson to serialize and deserialize JSON Patch and JSON Merge Patch operations using spray-json types. The implementation provides implicit formats for JSON Pointer, individual JSON Patch operations (add, remove, replace, move, copy, test), and the composite patch structures, along with a Jsony instance to bridge Diffson's internal JSON representation with spray-json's JsValue, JsArray, and JsObject types.

sprayJson/src/main · high confidence

Introduce JSON Pointer evaluation with RFC 6901 compliance

Added a new \jsonpointer\ package that provides a \Pointer\ type for navigating JSON documents. This implementation supports both string keys and integer array indices, correctly handles RFC 6901 escape sequences (\\~0\ and \\~1\), and uses a monadic \evaluate\ method to safely traverse JSON structures, raising errors for invalid paths or out-of-bounds array access.

core/src/main/scala/diffson/jsonpointer · high confidence

New JSON Merge Patch support and configurable JSON Patch diffing strategies

The library now includes a new JSON Merge Patch implementation (JsonMergeDiff and JsonMergePatch) alongside the existing JSON Patch capabilities. For JSON Patch, the diffing behavior is now configurable via two strategies: 'lcsdiff' (default, using Longest Common Subsequence for array diffs) and 'simplediff' (ignoring array order). Both strategies offer a 'remembering' variant that preserves old values in Remove and Replace operations, enabling more robust patch application and validation.

core/src/main/scala/diffson/jsonpatch · high confidence

Removals

Removal of Lift JSON implementation and core diffing classes

The core implementation files for the Lift JSON integration and the default JSON diffing logic have been removed. This includes the deletion of \JsonDiff.scala\, \JsonPatch.scala\, \JsonPointer.scala\, \Patience.scala\, and \package.scala\ from the \src/main/scala/gnieh/diffson\ directory. Consequently, the default \JsonDiff\ instance, the \JsonPatch\ and \JsonPointer\ classes, and the \Patience\ LCS algorithm that previously relied on \net.liftweb.json\ are no longer available in this location.

src/main · high confidence

Behavioural changes

Core library refactored to use a type-class based architecture

The core diffing and patching logic has been rewritten to rely on Scala type-classes rather than the previous implementation. New abstractions including \Diff\, \Patch\, and \Jsony\ define the interfaces for comparing JSON structures and applying patches, while \package.scala\ provides convenient extension methods (such as \diff\ and \apply\) and extractors (\JsObject\, \JsArray\) to simplify usage. This change shifts the library's design towards a more modular, type-driven approach for handling JSON operations.

core/src/main/scala/diffson · high confidence

Migrate build infrastructure to sbt 1.13 and Typelevel plugins

The project has migrated its build system from the legacy sbt 0.13 \Build.scala\ style to the modern sbt 1.x structure, setting the build version to 1.13.0. This change replaces the \sbt-osgi\ plugin with \sbt-typelevel\ (0.8.7) and adds support for cross-compilation to Scala.js (1.22.0) and Scala Native (0.5.12), alongside the \sbt-jmh\ benchmarking plugin.

project · high confidence

Refactored LCS algorithm implementations and interface

The Longest Common Subsequence (LCS) logic has been restructured to improve performance and code organization. The core interface, Lcs, now operates on List slices with explicit bounds rather than generic sequences, allowing implementations to avoid unnecessary data copying. New implementations include DynamicProgLcs, which uses a dynamic programming approach with optimized tail-recursive matrix filling, and Patience, which employs the patience sorting algorithm with an optional fallback to the dynamic programming method for cases where patience sorting cannot find the LCS. Additionally, HashedLcs provides a decorator that pre-computes hashes to speed up comparisons for objects with expensive hashCode calculations.

core/src/main/scala/diffson/lcs · high confidence

Upgrade to Diffson 4.1.1 with Cats-based API and multi-library support

The library has been updated to version 4.1.1, introducing a significant API shift from the legacy \gnieh.diffson\ package to \diffson\. This release adopts the Cats library for its type-class approach (using \MonadError\ for error handling) and adds support for RFC-7396 (JSON Merge Patches) alongside existing RFC-6901/6902 support. Users can now integrate with multiple JSON libraries including spray-json, play-json, circe, and ujson/upickle, and the library supports Scala 2.12, 2.13, and 3, as well as Scala.js. The diff computation logic has also been updated to use an LCS-based implementation for better handling of array changes.

(repo-wide) · high confidence

Test coverage

Added Circe conformance tests for JSON Patch; Added Circe-specific test suite for JSON diffing operations; Added Play JSON conformance tests for JSON Patch; Added Spray JSON conformance tests; Added benchmarks for the Patience LCS diff algorithm; Added shared testkit for JSON Patch, Merge Patch, and Diff conformance; Added test suite for spray-json integration; Added tests for LCS algorithms; Removed legacy Lift-json based test suite.

Dependencies

Update core and module dependencies to latest versions

The build configuration updates several key dependencies: Scala versions are set to 2.12.21, 2.13.18, and 3.3.8; test libraries are upgraded to scalatest 3.2.20 and scalacheck 1.20.0; and core libraries are updated to scala-collection-compat 2.14.0 and cats-core 2.13.0. Module-specific dependencies are also refreshed, including play-json 3.1.0-M10, circe 0.14.16, and ujson/upickle 4.4.3.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 62.

Lenses

  • Code Health 97
  • Architecture 100
  • Maturity 58
  • Readiness 53
  • Security 70

Changes since last survey

  • 300 commits — 285 feature/other, 15 fixes

By area

  • (repo) — 131 commits
  • (root) — 86 commits
  • project/plugins.sbt — 30 commits
  • .github/workflows — 15 commits
  • project/build.properties — 14 commits
  • core/src — 11 commits
  • testkit/shared — 4 commits
  • ujson/shared — 4 commits
  • circe/shared — 3 commits
  • playJson/shared — 2 commits

Notable commits

  • fix: Fix build & some Scala 3 warnings
  • fix: Fix interpretation of integer segment on objects
  • fix: Fix newline at end of file in plugins.sbt
  • fix: Fix organization name
  • fix: Fix simple diff with remember
  • fix: Fix some warnings
  • fix: Fix stack overflow when diffing wide objects
  • fix: Fix travis if-else
  • fix: Merge pull request #301 from gnieh/fix/275/remember-simple
  • fix: Merge pull request #302 from gnieh/fix-org-name
  • fix: Merge pull request #468 from gnieh/fix-base-version
  • fix: Merge pull request #470 from gnieh/port-stack-overflow-fix
  • fix: fix codacy complaints
  • fix: fix eviction warning
  • fix: fix multibuild and use version supported by native and js
  • change: Add native build for play-json module
  • change: Avoid deep recursive object equalities
  • change: Avoid list traversal to get indices
  • change: Avoid systematic potentially heavy equality check at first
  • change: Benchmark LCS diff implementation
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

gnieh/diffson was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit d5f2ffabae88a4d1359aaa3916e2fc16dc95d203 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.