serialkompat
A backward/forward compatibility gate for kotlinx-serialization @Serializable models — like buf breaking, but for JSON.
You delete a field. Payloads in queues, caches, and old app versions still carry it:
The one-line change on your PR
@Serializable
data class Order(
val id: String,
val amountCents: Long,
- val note: String? = null,
)
$ ./gradlew serialkompatCheck
serialkompat: 1 active finding(s) (1 breaking, 0 warning), 0 acknowledged
BREAK PROPERTY_REMOVED com.example.Order (backward)
field 'note' was removed from com.example.Order
fix: Removing a field drops its data for tolerant readers; keep it (or bridge a rename with @JsonNames) until nothing uses it; else bump major.
BUILD FAILED
serialkompat compares your models against a baseline: the schema at a git ref, usually your target branch. It extracts that baseline live on every run, so there is no baseline file to maintain.
Every change is checked in both directions. Backward compatible means new code can
read old data. Forward compatible means old code can read new data. Each verdict
reflects how real kotlinx-serialization behaves under your actual Json { } config.
How it works
@Serializable
Extractor
Snapshot
Differ
Classifier
Report
@Serializable: your compiled Kotlin models.- Extractor: walks the runtime
SerialDescriptorgraph on the JVM, so it sees exactly what goes on the wire. - Snapshot: a canonical, comparable model of that wire schema.
- Differ: lists the changes between two snapshots.
- Classifier: applies the rules and your real
Json { }config to turn each change into a finding with a severity. - Report: the findings plus an exit code, printed to the console. It is also available as JSON, SARIF, and GitHub annotations.
Is / is not
| serialkompat is | serialkompat is not |
|---|---|
A CI gate for JSON wire/persisted-schema evolution of @Serializable models |
A runtime validator |
Direction-aware (BACKWARD / FORWARD / FULL) and config-aware (ignoreUnknownKeys, namingStrategy, encodeDefaults, …) |
A migration tool |
| Grounded in real kotlinx-serialization behavior — every rule is backed by a round-trip oracle test | A replacement for API/schema versioning |
| A general-purpose JSON-schema linter |
Install
The plugin is on the
Gradle Plugin Portal, so
a plain plugins { id("com.chrisjenx.serialkompat") version "0.2.0" } works; see
Setup. Development happens in the open; see the
issues and
milestones.