What is the difference between languageVersion and apiVersion compiler options, and when would you set each?
answer
- languageVersion = syntax/features the compiler accepts
- apiVersion = which stdlib declarations you may call
- apiVersion <= languageVersion
- Both default to the compiler's own version
- Lower languageVersion to stage a compiler upgrade
basics
~10 slanguageVersion controls which Kotlin syntax/features the compiler accepts; apiVersion controls which version of the standard library you're allowed to call. You usually lower them to stay compatible with older consumers.
solid answer
~40 scompilerOptions.languageVersion sets the version of the Kotlin language the compiler enforces — features newer than that version are reported as errors, letting you compile new-compiler code against older language semantics (source compatibility / a deprecation runway). compilerOptions.apiVersion restricts which kotlin-stdlib (and bundled library) declarations you may reference: APIs introduced after the chosen apiVersion are forbidden, so your artifact stays runnable against an older stdlib. They're independent: you can run Kotlin 2.x's compiler with languageVersion=2.0 and apiVersion=1.9, for example. apiVersion must be <= languageVersion. Both default to the compiler's own version. Common uses: library authors lowering apiVersion to support consumers on older stdlibs, or teams lowering languageVersion temporarily to ease a compiler upgrade before adopting new syntax.
go deeper
Recognizes both exist and relate to Kotlin version compatibility, even if fuzzy on which is which.
Clearly distinguishes language (syntax) from API (stdlib), knows apiVersion <= languageVersion and the defaults.
Uses them to stage compiler upgrades and to keep a library compatible with older stdlibs on consumers' classpaths.
Defines an org policy for version pinning across a library ecosystem, reasoning about N-1/N-2 support windows and binary compatibility.
## The two knobs Kotlin separates *which language you write in* from *which standard library you call*: - **`languageVersion`** — the version of the **Kotlin language** the compiler enforces. Source-level features (new syntax, new keywords, new semantics) added after this version are rejected with errors. Setting `languageVersion = 2.0` while using a 2.2 compiler means: "use the new compiler binary, but only let me write Kotlin-2.0 source." - **`apiVersion`** — the maximum version of the **Kotlin standard library / dependent libraries** whose declarations you're allowed to reference. Any stdlib function/class introduced *after* `apiVersion` is a compile error. This keeps the produced artifact runnable against an **older `kotlin-stdlib`** on the classpath. ```kotlin kotlin { compilerOptions { languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9) } } ``` ## Why they're independent You can mix them. A library that ships to consumers stuck on an old stdlib might use a brand-new compiler (for bug fixes/speed) but set `apiVersion = 1.9` so it never *links against* stdlib symbols those consumers lack. The rule: **`apiVersion` must be ≤ `languageVersion`** — you can't call APIs from a language version you've forbidden yourself from speaking. ## Defaults and the deprecation runway Both default to the **compiler's own version** (e.g. with the 2.2 compiler, both default to 2.2). The Kotlin team typically supports the current version and **N-1 / N-2** for these options. Lowering `languageVersion` is the standard way to **stage a compiler upgrade**: bump the Kotlin Gradle plugin (faster compiler, fixes) while temporarily pinning `languageVersion` to the old one, then drop the pin once the team adopts the new syntax. ## Contrast with jvmTarget - `jvmTarget` → JVM **bytecode** format. - `languageVersion` → Kotlin **source language** level. - `apiVersion` → Kotlin **stdlib API** surface you may use. These are three orthogonal dials.
- Can apiVersion be higher than languageVersion?No. The compiler requires apiVersion <= languageVersion, because you cannot reference APIs from a language version you have disabled.
- Why use a newer compiler with an older languageVersion?To get the new compiler's speed and bug fixes immediately while giving the team a runway to migrate source before adopting new language features.
saying these in an interview costs you the question
- Saying languageVersion and apiVersion are the same thing
- Confusing either with jvmTarget / bytecode level
- Claiming apiVersion can exceed languageVersion
- Thinking these change which JDK is used
- Not knowing they default to the compiler's version