skip to content

What is the kotlinx binary-compatibility-validator, and what problem does it solve for a Kotlin library?

level: juniorimportance: should knowfreq 35%

answer

  1. Guards public ABI, not just source compat
  2. Checked-in .api files
  3. apiDump regenerates, apiCheck fails build
  4. apiCheck wired into `check`
  5. API delta visible in PR review

basics

~20 s

It is a tool that records your library's public API into text files. If a change accidentally removes or alters that public API, the build fails, warning you before you break code that depends on your library.

solid answer

~40 s

binary-compatibility-validator (BCV) is a Gradle plugin (`org.jetbrains.kotlinx.binary-compatibility-validator`) that snapshots a library's public Application Binary Interface (ABI) into checked-in `.api` files. It adds two tasks: `apiDump` regenerates the `.api` snapshot from the current code, and `apiCheck` (wired into `check`) compares the current public ABI against the committed `.api` and fails the build on any difference. This catches accidental breaking changes — a removed `public` function, a changed signature, a narrowed visibility — that would break already-compiled consumers needing a recompile or breaking them at link time. The `.api` files are reviewed in pull requests, making API surface changes explicit and intentional rather than silent.

go deeper

for a junior

Knows it snapshots the public API into files and fails the build when the API changes unexpectedly.

for a middle

Distinguishes apiDump vs apiCheck, knows .api files are committed and reviewed, and that apiCheck hooks into check.

for a senior

Frames it around ABI vs source compatibility and downstream runtime errors; treats the .api as a reviewable contract artifact.

for a principal

Positions BCV in a library's release/governance policy: enforced in CI, paired with SemVer rules and explicit-API mode for a deliberate public surface.

## What it is `binary-compatibility-validator` (BCV) is a JetBrains/kotlinx Gradle plugin that guards the **public ABI** (Application Binary Interface) of a Kotlin library. It is applied as `org.jetbrains.kotlinx.binary-compatibility-validator`. ## ABI vs source compatibility - **Source compatibility**: consumer source still *compiles* against the new version. - **Binary compatibility (ABI)**: consumer code already *compiled* against the old version still *links and runs* against the new JAR without recompilation. Breaking the ABI means a `NoSuchMethodError`/`AbstractMethodError` at runtime for downstream users. BCV protects the second guarantee, which matters for any published library. ## How it works BCV computes a textual dump of every element reachable through the public API surface (public/protected classes, functions, properties, with their JVM signatures) and stores it in a checked-in file, conventionally `api/<module>.api`. It contributes two Gradle tasks: - **`apiDump`** — regenerates the `.api` file(s) from the current compiled output. You run this intentionally when you change the API. - **`apiCheck`** — recomputes the current public ABI and diffs it against the committed `.api`; **fails the build** on any mismatch. It is wired as a dependency of the standard `check` task, so `./gradlew check` enforces it in CI. ```kotlin // build.gradle.kts (root) plugins { kotlin("jvm") version "2.1.0" id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.17.0" } ``` ## The workflow 1. Add a new `public` function → `apiCheck` fails because the `.api` no longer matches. 2. Run `./gradlew apiDump` to update the `.api`. 3. Commit the updated `.api` alongside the code; reviewers see the API delta in the diff. Making the API surface a **reviewable artifact** is the core value: breaking changes become visible and deliberate instead of slipping through unnoticed.

  • Where are the dump files stored by default and should they be committed?
    In an `api/` directory next to the module (e.g. `api/<module>.api`). Yes — they are committed to version control so changes appear in pull requests.
  • Which standard Gradle task triggers apiCheck?
    `check` — the plugin makes `apiCheck` a dependency of `check`, so any CI step running `./gradlew check` enforces it.

Like a checked-in snapshot test for your library's public API: the build fails the moment the snapshot drifts unexpectedly.

saying these in an interview costs you the question

  • Thinking it lints code style rather than the public API surface
  • Confusing it with detekt/ktlint quality tools
  • Claiming it auto-fixes the .api on every build (apiDump is manual/intentional)
  • Believing it only checks source compatibility, not binary

context