SYSTEM Cited by 1 source
Kotlin binary compatibility validator¶
Definition¶
The Kotlin binary compatibility validator is a JetBrains- maintained Gradle plugin (github.com/Kotlin/binary-compatibility-validator) that captures a Kotlin library's public ABI as a check-in artefact and fails CI if a code change would alter that ABI in a way that breaks consumers compiled against the previous version.
The wiki's first canonical citation is via Airbnb's
Viaduct 1.0 announcement, which names the
validator as the CI gate enforcing the project's
@StableApi /
@ExperimentalApi / @InternalApi discipline. (Source:
sources/2026-05-13-airbnb-viaduct-1-0-and-the-future-of-airbnbs-data-mesh)
What it does¶
The validator's mechanic is straightforward:
- Dump the public ABI. A Gradle task scans the project's
compiled bytecode, extracts every public class, function,
property, and constructor, and writes them to a
.apifile that lives in the repository (typically underapi/). - Diff in CI. On each build, the dump is regenerated from
the current code and diffed against the checked-in
.apifile. - Fail on drift. If the dump differs and the change isn't
the expected one (i.e. the developer hasn't updated the
.apifile alongside the code change), the build fails.
This forces every ABI change to be explicit — the developer must regenerate and check in the new dump as part of the PR. Reviewers can then see the exact ABI delta in the PR diff.
Annotation-aware filtering¶
The validator can be configured to ignore elements annotated with project-specific markers — typically internal- use or experimental-use annotations. A common Kotlin/JVM configuration:
apiValidation {
ignoredClasses.addAll(listOf(/* generated stuff */))
nonPublicMarkers.addAll(listOf(
"com.example.InternalApi",
"com.example.ExperimentalApi"
))
}
This is the integration point with the
@StableApi /
@ExperimentalApi / @InternalApi pattern: only @StableApi
elements (everything not annotated with the non-public markers)
are tracked by the validator. ABI changes to elements marked
non-stable don't fail the build; ABI changes to @StableApi
elements do.
Why this matters at the OSS 1.0 line¶
Pre-1.0, breaking-change discipline can be informal. Post-1.0, the "don't break consumers compiled against the previous version" contract has to be machine-checkable, because:
- Consumers are no longer in your monorepo where you can refactor them in lockstep.
- Consumers' binaries (e.g. application JARs) are linked against a specific version of your library, and re-linking is a customer cost.
- A typo'd refactor that accidentally changes a method
signature is otherwise invisible until a downstream consumer
builds against the new version and gets a
NoSuchMethodErrorat runtime.
Viaduct's 1.0 announcement names the post-1.0 disclipline shift in those terms (verbatim): "Until now, Viaduct has evolved rapidly to meet internal needs, often with breaking changes managed through our internal monorepo tooling. Public release required a different approach."
Coverage limits¶
- Bytecode level only. The validator catches ABI changes
(signatures, modifiers, type parameters). It does not
catch:
- Behavioural changes to a method whose signature stays the same.
- Changes to documented exception-throwing semantics.
- Implicit ordering / sorting / iteration-order changes.
- Changes to which IO / DB calls a method makes.
- Java consumers see the JVM ABI. Kotlin features that desugar to JVM bytecode (data classes, default arguments, inline functions, sealed classes) are tracked at the desugared level. A change that's source-compatible from Kotlin but alters the desugared bytecode is still a breaking change for Java consumers and will fail the validator.
- Generated code can be noisy. Kotlin Symbol Processing
(KSP) / kapt-generated bytecode often shows up in the dump
and needs explicit
ignoredClassesfiltering.
Adjacent tools¶
- Java:
revapi,japicmp,jdiff— the JVM ecosystem's Java-source-and-bytecode-comparison tools, all older than the Kotlin validator and all without first-class Kotlin understanding. - Rust:
cargo-semver-checks— same shape (track public API as a check-in artefact, fail CI on unexpected change), newer. - Python: no widely-adopted equivalent at the package level; PEP 600 stable-ABI for CPython extensions covers a narrower scope.
- C++:
abi-compliance-checker— long-standing tool, more manual.
The Kotlin validator's specific value is its idiomatic Kotlin understanding + Gradle integration + annotation- based filter — none of the Java-era tools handle Kotlin's desugaring decisions or annotation conventions natively.
Seen in¶
- sources/2026-05-13-airbnb-viaduct-1-0-and-the-future-of-airbnbs-data-mesh
— first canonical wiki citation. Viaduct's 1.0 announcement
names the validator as the CI gate enforcing the project's
@StableApi/@ExperimentalApi/@InternalApidiscipline.
Related¶
- systems/viaduct — the wiki's first instance using it
- patterns/api-stability-annotations — the discipline this tool enforces
- companies/airbnb — the OSS publisher