Skip to content

Repository files navigation

Library API Watchdog library-api-watchdog logo

A Kotlin K2 compiler plugin that warns library authors about public API declarations that are hard to evolve.

Documentation - a full write-up for every check: rationale, do/don't examples, exemptions, and configuration. The API reference covers the exemption annotations.

Setup

Add the snapshot repository to settings.gradle.kts for both plugin and library resolution:

pluginManagement {
    repositories {
        maven("https://packages.jetbrains.team/maven/p/kt-lib/eap")
        gradlePluginPortal()
    }
}

dependencyResolutionManagement {
    repositories {
        maven("https://packages.jetbrains.team/maven/p/kt-lib/eap")
        mavenCentral()
    }
}

The plugin only runs in modules compiled with explicit API mode (strict or warning variant). Without it the checkers are not registered at all, and the Gradle plugin prints a warning.

plugins {
    kotlin("library.api-watchdog") version "<version>"
}

kotlin {
    explicitApi()
}

Applying the Gradle plugin registers the compiler plugin for every compilation except test compilations, whose sources are never published, and automatically adds the org.jetbrains.kotlin:kotlin-library-api-watchdog-plugin-annotations dependency with the @Intentionally* exemption annotations. The plugin is intentionally restrictive by default: every check reports a compilation error until it is individually demoted to a warning or disabled through the apiWatchdog extension:

import org.jetbrains.kotlinx.libs.api.watchdog.WatchdogSeverity

apiWatchdog {
    undocumentedPublicApi = WatchdogSeverity.WARNING
    javaInterop {
        enabled = false // A Kotlin-only library can drop the whole Java interop group.
    }
}

See Setup and the Gradle plugin reference for all options, including direct compiler invocation without Gradle.

Exemptions

Declarations that are public for technical reasons only are excluded from all checks by marking the library's internal-API annotation with @InternalAnnotationMarker. A single declaration is exempted in place with the matching @Intentionally* annotation, which must explain itself through an ExemptionReason and a description. See Exemptions and internal API.

Adopting on an existing library

A library that has already shipped can't change the shape of its public API without breaking users, so the watchdog's first run typically floods it with diagnostics that are not actionable anymore. The Gradle plugin registers an updateBackwardsCompatibilityExempts task that acknowledges all of them in one sweep:

./gradlew updateBackwardsCompatibilityExempts

The task depends on the regular main Kotlin compilation tasks for every KGP target, including JS, Native, Wasm, and metadata-only projects. Those compilations record diagnostics with their exact source positions. The task merges and deduplicates the reports, then inserts the matching @Intentionally* annotations with reason = ExemptionReason.FOR_BACKWARDS_COMPATIBILITY (adding imports as needed). A markerless @SubclassOptInRequired is replaced by @IntentionallyOpen rather than annotated, since it restricts nothing to begin with. Checks disabled through apiWatchdog are not exempted, and the few diagnostics no annotation can acknowledge are listed as warnings for manual follow-up. Enabled always-error diagnostics must be fixed before the task can run. Run it on a clean working tree and review the diff. From then on the checks only guard newly added API. See the existing-library guide for details.

Checks

API surface

Java interop

These checks only run in JVM compilations. A Kotlin-only library disables the group with javaInterop { enabled = false }. See the group overview.

DSL markers

Exemption hygiene

Build-level suggestions

Performed by the Gradle plugin rather than the compiler:

Development

The build resolves compiler-plugin-dev-kit from its Space EAP repository. The dev-kit settings plugin supplies its Kotlin development repositories, aligned plugin coordinates, and functional-test publishing setup. The supported Kotlin versions, companion library, and compiler-plugin project are declared through the dev-kit's namespaced properties in gradle.properties.

Tests:

./gradlew :kotlin-library-api-watchdog-compiler-plugin:test               # diagnostics tests
./gradlew :kotlin-library-api-watchdog-compiler-plugin:generateTests      # regenerate JUnit classes from test data
./gradlew :kotlin-library-api-watchdog-gradle-plugin:functionalTest       # Gradle integration tests

Modules:

The documentation site is a Docusaurus project in docs, built by docs.yml. See docs/authoring.md for the page template and rules.

About

A Kotlin compiler plugin that helps library authors keep their public API easy to evolve

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages