skip to content

What is build.gradle.kts, and how does it differ from build.gradle when describing a Gradle project?

level: juniorimportance: must knowfreq 70%

answer

  1. Kotlin DSL vs Groovy DSL
  2. .kts = compiled Kotlin script
  3. static typing + IDE autocomplete
  4. implicit Project receiver
  5. slower first run, cached

basics

~20 s

build.gradle.kts is a Gradle build script written in Kotlin (the Kotlin DSL), instead of build.gradle which uses the Groovy DSL. Both configure the same project; the .kts file is Kotlin source compiled before the build runs.

solid answer

~40 s

`build.gradle.kts` is a Gradle build script authored in the **Kotlin DSL**. Functionally it does the same job as a Groovy `build.gradle`: it configures a `Project` — applying plugins, declaring dependencies, configuring tasks. The difference is the language. `.kts` is a real Kotlin script: it is statically typed and compiled to JVM bytecode before execution, so the IDE can offer accurate autocompletion, navigation and refactoring, and many mistakes surface as compile errors rather than runtime failures. The trade-off is slower first-time configuration (scripts must be compiled and the compiled output cached) and a stricter, less dynamic syntax than Groovy. You pick one DSL per script; Gradle resolves whichever file is present.

code

kotlin · 11 lines
kotlin
plugins {
    java
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.google.guava:guava:33.0.0-jre")
}

go deeper

for a junior

Know that .kts means Kotlin DSL and .gradle means Groovy DSL, and both configure the project.

for a middle

Explain static typing, compilation, IDE autocompletion and the first-run compile cost trade-off.

for a senior

Discuss when to choose Kotlin DSL for a team (tooling, refactor safety) versus Groovy's flexibility, and the implicit Project receiver.

for a principal

Weigh DSL choice as an org standard: migration cost, plugin/convention reuse, onboarding, and build-performance implications across many modules.

## What a build script is Every Gradle build is driven by build scripts. The root script and each module's script configure a `Project` object. A build script is *not* a static config file — it is a program that, when run, mutates the build model (plugins, dependencies, tasks, extensions). Gradle supports two DSLs for writing these scripts: - **Groovy DSL** — file named `build.gradle`. Dynamically typed, very flexible, the historical default. - **Kotlin DSL** — file named `build.gradle.kts`. Statically typed Kotlin. ## How `build.gradle.kts` works The `.kts` extension means "Kotlin script". Gradle compiles your script into JVM bytecode using the Kotlin compiler, then executes it. The script body runs with an **implicit receiver** of type `Project` (technically a `KotlinBuildScript`), which is why you can call `dependencies { }`, `plugins { }`, `tasks { }` etc. directly without qualifying them — they are members on the receiver. Because it is compiled Kotlin: - **Static typing** — accessors, extension functions and configuration blocks have real types, so the IDE gives precise autocompletion and ctrl-click navigation. - **Compile-time checking** — a typo in a property name or a wrong argument type fails compilation, not at task-execution time. - **Refactoring** — rename/extract works like in any Kotlin code. ## The trade-offs vs Groovy | Aspect | Groovy DSL | Kotlin DSL | |---|---|---| | Typing | Dynamic | Static | | IDE support | Weaker autocomplete | Strong autocomplete | | First-run cost | Faster | Slower (compile + cache scripts) | | Errors | Often at runtime | Often at compile time | The Kotlin DSL must compile scripts, so the *first* configuration after a change is slower; compiled scripts are cached so subsequent runs are fast. ## Picking a DSL A module uses exactly one script file. If both `build.gradle` and `build.gradle.kts` exist, that is a mistake — pick one. New projects increasingly default to Kotlin for the tooling benefits. ```kotlin // build.gradle.kts — a minimal script plugins { java } repositories { mavenCentral() } dependencies { implementation("com.google.guava:guava:33.0.0-jre") } ```

  • Why does the first build after editing a .kts script feel slower than with Groovy?
    Because Gradle compiles the Kotlin script to bytecode before running it; that compilation is cached, so only the first run after a change pays the cost.
  • Can you mix build.gradle and build.gradle.kts in the same project?
    Yes across different modules — each module can use its own DSL — but a single module should have only one script file, not both.

saying these in an interview costs you the question

  • Claiming Kotlin DSL and Groovy DSL configure different build models — they configure the same Project.
  • Saying .kts is interpreted line-by-line; it is compiled to JVM bytecode.

context