How do you opt in to an experimental marker for an entire module via the compiler, and what are the trade-offs versus per-declaration @OptIn?
answer
- -opt-in=fully.qualified.Marker
- Gradle: compilerOptions { optIn.add(...) }
- Module-wide = DRY but not greppable
- @OptIn = explicit, reviewable per site
basics
~20 sYou can tell the compiler to accept a marker everywhere in the module using a build setting instead of writing @OptIn on every spot. It's convenient but you lose the per-use record of where the risky API is used.
solid answer
~40 sPass the fully qualified marker to the compiler with -opt-in=pkg.Marker. In a Kotlin Gradle build you configure it via kotlin { compilerOptions { optIn.add("kotlinx.coroutines.ExperimentalCoroutinesApi") } } (older API: kotlinOptions/freeCompilerArgs += "-opt-in=..."). This blanket-accepts the marker across the whole module, so no per-declaration @OptIn is needed. Trade-off: it's DRY and great when an experimental marker is pervasive and the team has consciously accepted it (e.g. a coroutines-heavy module accepting ExperimentalCoroutinesApi). But it removes the local, greppable acknowledgement at each call site, makes accidental new usages invisible, and applies to the entire module rather than letting you keep risky usage contained. For sparse or risky usage, prefer narrowly-scoped @OptIn so each acceptance is explicit and reviewable.
code
kotlin · 6 lines// build.gradle.kts
kotlin {
compilerOptions {
optIn.add("kotlinx.coroutines.ExperimentalCoroutinesApi")
}
}go deeper
Aware that a build setting can accept a marker globally instead of per-use.
Configures optIn.add / -opt-in correctly and states the DRY-vs-auditability trade-off.
Decides per-marker whether module-wide or per-site is appropriate based on pervasiveness and risk.
Establishes module conventions (which markers are blanket-accepted) and bakes them into shared build config.
## The module-wide flag Instead of sprinkling `@OptIn` everywhere, you can accept a marker for the whole compilation unit using the compiler argument: ``` -opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi ``` ## Gradle configuration Modern Kotlin Gradle DSL: ```kotlin kotlin { compilerOptions { optIn.add("kotlinx.coroutines.ExperimentalCoroutinesApi") } } ``` Older/legacy style: ```kotlin tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { kotlinOptions { freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi" } } ``` The special value `-opt-in=kotlin.RequiresOptIn` historically silenced the meta-warning about *using* the opt-in mechanism itself (relevant on older Kotlin versions when the feature was itself experimental). On current Kotlin 2.x the mechanism is stable and this is unnecessary. ## Trade-offs vs `@OptIn` | Aspect | Module flag (`-opt-in`) | Per-declaration `@OptIn` | |---|---|---| | Boilerplate | None — set once | One annotation per use site | | Auditability | Low — usage not visible in code | High — greppable at each site | | Accidental new usage | Silently allowed | Forces a fresh, reviewed acknowledgement | | Scope | Whole module | Exactly where written | ## When to use which - **Module flag**: the marker is pervasive and the team has deliberately committed to it (e.g. a module built entirely on experimental coroutine APIs). Saves noise. - **`@OptIn`**: sparse, risky, or security/stability-sensitive usage where you want each acceptance to be explicit, local, and reviewable. ## Combining You can mix: use the flag for a truly pervasive marker and `@OptIn` for rarer ones — keeping the rare acceptances visible.
- What's the downside of opting in module-wide for a marker that's only used in two places?You lose the explicit, greppable acknowledgement at those sites, and any new accidental usage of the experimental API elsewhere in the module compiles silently — eroding auditability for little boilerplate saved.
saying these in an interview costs you the question
- Not knowing the marker must be fully qualified in the flag
- Confusing optIn.add(...) with adding a dependency
- Claiming the module flag only affects one file
- Ignoring the auditability cost of blanket opt-in