How do you enable Explicit API mode in a Kotlin Gradle build, and what is the difference between strict and warning levels?
answer
- explicitApi() = strict (errors), explicitApiWarning() = warning
- explicitApi = ExplicitApiMode.Strict/Warning/Disabled
- Sugar over -Xexplicit-api=...
- Start warning, migrate, then flip strict
- Scope to library/main, skip tests
basics
~10 sIn your Gradle build script's kotlin block, call explicitApi() for strict mode (build fails) or explicitApiWarning() for warnings only. Under the hood it passes a -Xexplicit-api compiler flag.
solid answer
~40 sIn the Kotlin Gradle DSL, the kotlin { } extension exposes explicitApi() and explicitApiWarning(). explicitApi() sets strict mode, which surfaces violations as compilation errors and fails the build; explicitApiWarning() reports the same issues as warnings without failing. Both are sugar over the compiler argument -Xexplicit-api=strict / -Xexplicit-api=warning, which you can also pass directly via freeCompilerArgs (or the older kotlinOptions). You can also set the explicitApiMode property to ExplicitApiMode.Strict, Warning, or Disabled. A common pattern is enabling it for published library modules but not for test or sample source sets, since tests don't need a curated public surface — Gradle applies it to the main compilation but you can scope it as needed.
code
kotlin · 12 lineskotlin {
explicitApi() // strict
}
// equivalent low-level form:
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
kotlin { explicitApi = ExplicitApiMode.Strict }
// raw flag:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
compilerOptions.freeCompilerArgs.add("-Xexplicit-api=strict")
}go deeper
Knows you add explicitApi() in the kotlin block.
Distinguishes explicitApi() strict from explicitApiWarning(), and names the ExplicitApiMode enum / -Xexplicit-api flag.
Describes a warning-to-strict migration and CI enforcement, and scoping to main vs test.
Standardizes the policy across many library modules (convention plugin), balances strictness with build noise, and ties it into release governance.
## Enabling it via the Kotlin Gradle DSL The `kotlin { }` extension provides two convenience functions: ```kotlin // build.gradle.kts kotlin { explicitApi() // strict — violations are ERRORS, build fails // explicitApiWarning() // warnings only — build still succeeds } ``` These are shorthand for setting the **`explicitApiMode`** property: ```kotlin import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode kotlin { explicitApi = ExplicitApiMode.Strict // or .Warning or .Disabled } ``` ## The underlying compiler flag Both helpers ultimately add a compiler argument: - `-Xexplicit-api=strict` - `-Xexplicit-api=warning` - `-Xexplicit-api=disable` You can pass it manually if you prefer or need finer control: ```kotlin tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach { compilerOptions.freeCompilerArgs.add("-Xexplicit-api=strict") } ``` ## Strict vs warning | Mode | Reported as | Build outcome | |------|-------------|---------------| | **strict** (`explicitApi()`) | compile **errors** | **fails** on any violation | | **warning** (`explicitApiWarning()`) | compile **warnings** | succeeds | | **disable** | nothing | succeeds | The `-X` prefix means these are still technically experimental/advanced compiler flags, but the Gradle DSL functions are the stable, recommended entry point. ## Scoping The Kotlin Gradle plugin applies the mode to the module's compilations. **Test source sets do not need a curated public API**, so a typical approach is to enable it on library/main modules only — application and test modules usually leave it off. A migration strategy is to start with `explicitApiWarning()`, clean up the reports incrementally, then flip to `explicitApi()` and wire it into CI so regressions fail the build.
- How would you migrate a large existing library to strict mode without breaking CI immediately?Turn on explicitApiWarning() first, fix the reported declarations gradually, then switch to explicitApi() and let CI enforce it.
- Should you enable it on test source sets?Usually not — tests have no curated public surface, so the curation noise adds no value there.
saying these in an interview costs you the question
- Saying explicitApi() only warns instead of failing the build
- Not knowing it maps to -Xexplicit-api
- Claiming there's no warning-only level
- Thinking you must edit the compiler invocation manually — the DSL function exists
- Confusing it with enabling a separate plugin