What actually turns your Kotlin source into runnable artifacts, and what role does Gradle (or Maven) play in that process?
answer
- kotlinc compiles, Gradle/Maven orchestrates
- kotlin("jvm") plugin registers compileKotlin
- JVM target emits standard .class bytecode
- jvmTarget/languageVersion are compiler options
- K2 frontend in Kotlin 2.x
basics
~20 sThe Kotlin compiler, kotlinc, turns your .kt files into class files. Gradle or Maven is the build tool that calls the compiler for you, downloads libraries, and packages the output. The build tool drives the compiler.
solid answer
~30 sKotlin source is compiled by the Kotlin compiler, kotlinc. You almost never invoke it directly; a build tool drives it. With Gradle you apply the org.jetbrains.kotlin.jvm plugin, which registers compileKotlin tasks that invoke the compiler. Maven uses the kotlin-maven-plugin. The build tool resolves dependencies, sets the JVM target and language/API versions via compilerOptions (e.g. jvmTarget = JvmTarget.JVM_17), runs the compiler, then packages a JAR. For the JVM target, kotlinc emits standard .class bytecode that runs on any JVM; Kotlin/Native and Kotlin/JS are separate backends. The compiler itself is just a program; Gradle/Maven provide incremental compilation, caching, and dependency wiring around it.
code
kotlin · 15 linesplugins {
kotlin("jvm") version "2.1.0"
}
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
// languageVersion / apiVersion also live here
}
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}
// ./gradlew build -> Gradle invokes kotlinc, then packages a JARgo deeper
Knows kotlinc compiles and Gradle/Maven runs the build, and that JVM output is .class bytecode.
Can name the Kotlin Gradle plugin, the compileKotlin task, and where jvmTarget/languageVersion are configured.
Explains what the build tool adds (incremental compilation, caching, dependency resolution, plugin/KSP wiring) and the K2 frontend / multiple backends.
Reasons about build performance trade-offs (incremental compilation correctness, daemon reuse) and consistent toolchain/jvmTarget governance across many modules.
## The pieces There are two distinct things people conflate: - **The compiler** — `kotlinc`. This is the program that reads `.kt` files and produces output. On the JVM that output is JVM **bytecode** (`.class` files); Kotlin also has **Kotlin/Native** (native binaries via LLVM) and **Kotlin/JS** (JavaScript) backends. Modern Kotlin (2.x) uses the **K2** compiler frontend. - **The build tool** — **Gradle** or **Maven**. This is what you actually run (`./gradlew build`). It resolves dependencies, decides *what* to compile, and *invokes the compiler for you*. ## How Gradle drives the compiler You apply the Kotlin Gradle plugin: ```kotlin plugins { kotlin("jvm") version "2.1.0" } kotlin { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) } } ``` Applying the plugin registers tasks like `compileKotlin` and `compileTestKotlin`. When you run `./gradlew build`, Gradle: 1. Resolves declared dependencies from `dependencies { }`. 2. Runs `compileKotlin`, which invokes `kotlinc` with the right classpath and options. 3. Packages the resulting `.class` files into a JAR (`jar` task). Maven does the equivalent through the `kotlin-maven-plugin` bound to the `compile` phase. ## What the build tool adds on top of the compiler - **Dependency resolution** — pulls libraries (and the Kotlin stdlib) from repositories. - **Incremental compilation** — only recompiles changed sources. - **Build caching / up-to-date checks** — skips work when inputs are unchanged. - **Wiring of compiler plugins and symbol processors** (KSP/kapt) into the compile tasks. ## Key takeaway The compiler does the *compiling*; the build tool does the *orchestrating*. `jvmTarget`, `languageVersion`, and `apiVersion` are **compiler** options you configure *through* the build tool.
- Does the JVM run Kotlin bytecode differently from Java bytecode?No. For the JVM target, kotlinc emits standard JVM bytecode. The JVM cannot tell whether a class was written in Kotlin or Java; Kotlin just needs its stdlib on the classpath.
- Where do you set the target JVM version?In the build script via the Kotlin plugin: kotlin { compilerOptions { jvmTarget.set(JvmTarget.JVM_17) } }. It is a compiler option passed through Gradle.
The compiler is the oven; Gradle is the chef who gathers ingredients, sets the temperature, and decides what goes in.
saying these in an interview costs you the question
- Saying Gradle itself compiles Kotlin (it invokes kotlinc)
- Claiming the JVM needs a special Kotlin runtime engine to run the bytecode
- Confusing the build tool with the compiler
- Thinking Kotlin only targets the JVM (Native and JS backends exist)
- Setting jvmTarget in random places instead of compilerOptions