skip to content

What is the difference between build.gradle and build.gradle.kts, and what do you gain by choosing the Kotlin DSL?

level: juniorimportance: must knowfreq 70%

answer

  1. .gradle = Groovy, .gradle.kts = Kotlin
  2. Kotlin DSL is compiled and type-safe
  3. IDE: autocomplete, errors, refactor, navigation
  4. '=' assignment, double quotes, parentheses
  5. Cold compile cost but same Gradle API

basics

~10 s

build.gradle uses the Groovy language; build.gradle.kts uses Kotlin. The Kotlin version is type-checked, so the IDE gives autocompletion, error highlighting, and reliable refactoring before you run the build.

solid answer

~40 s

A `build.gradle` file is written in Groovy (dynamic, loosely typed); a `build.gradle.kts` file is written in Kotlin (statically typed). Gradle compiles the `.kts` script against the project's type-safe model, so IntelliJ/Android Studio can offer real autocompletion, jump-to-source, inline documentation, and refactoring, and many mistakes surface as red compile errors instead of runtime failures. You opt in simply by naming the file with the `.kts` extension; the build is then evaluated by the Kotlin scripting engine. Trade-offs: the Kotlin DSL has a slower first/cold script-compilation step and historically a steeper learning curve, but it is the recommended default for new Gradle projects. Both DSLs target the same Gradle API, so anything expressible in Groovy is expressible in Kotlin, just with explicit types and Kotlin syntax (named arguments, `=` assignments, lambdas with receivers).

code

kotlin · 14 lines
kotlin
// build.gradle.kts
plugins {
    kotlin("jvm") version "2.0.0"
}

group = "com.example"
version = "1.0.0"

repositories { mavenCentral() }

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
    testImplementation(kotlin("test"))
}

go deeper

for a junior

Knows the extension difference and that Kotlin gives IDE autocompletion and error checking.

for a middle

Explains it is a compiled, statically typed script and lists concrete IDE benefits and syntax differences.

for a senior

Discusses trade-offs (cold compile cost), migration mixing, and that both DSLs share one Gradle API.

for a principal

Frames DSL choice as a team-productivity/standardization decision and weighs compile cost vs. correctness across a large build.

## The two Gradle DSLs Gradle build scripts can be written in two languages, distinguished by file extension: - **`build.gradle`** — the **Groovy DSL**. Groovy is a dynamic JVM language; method and property names are resolved at runtime, so typos and wrong types are not caught until the build actually executes. - **`build.gradle.kts`** — the **Kotlin DSL**. `.kts` is a *Kotlin script* file. Kotlin is statically typed and compiled, so the script is checked against Gradle's typed object model before tasks run. ## What 'type-safe' buys you Because the Kotlin DSL is compiled, the IDE has a full type model of the build: - **Autocompletion** for tasks, configurations, plugin extensions (e.g. typing `java.` shows the real members of the `JavaPluginExtension`). - **Compile-time errors**: a misspelled property is red squiggle, not a 30-second build that fails at the bottom. - **Navigation & inline docs**: Ctrl/Cmd-click jumps into the plugin source; KDoc shows on hover. - **Refactoring**: rename a variable or extracted function and references update. ## Syntax differences you will see immediately ```kotlin // Kotlin DSL (build.gradle.kts) plugins { kotlin("jvm") version "2.0.0" } group = "com.example" // '=' assignment, not Groovy's space syntax version = "1.0.0" repositories { mavenCentral() } dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") testImplementation(kotlin("test")) } ``` Key contrasts vs Groovy: strings always use double quotes, properties are set with `=`, methods take parentheses, and configuration blocks are **lambdas with receivers** (the `{ }` block runs against a typed receiver object). ## Opting in / interop You choose the DSL purely by the file name (`settings.gradle.kts`, `build.gradle.kts`). A single project may even mix module files of each kind during a migration. Both DSLs call the **same Gradle API**, so functional capability is identical. ## Trade-offs - The Kotlin DSL incurs a one-time **script compilation** cost (cached afterward), so a cold build is a little slower than Groovy. - It is stricter, which means slightly more ceremony but far fewer silent mistakes. - It is the **recommended default for new builds** in modern Gradle and Android Studio templates.

  • Can you mix .gradle and .gradle.kts files in the same multi-module build?
    Yes. Each module's build script is independent, so you can migrate module by module; both DSLs target the same Gradle API.
  • Why might a cold Kotlin DSL build feel slower than Groovy?
    The Kotlin script must be compiled before evaluation. The result is cached, so only the first run (or after a script change) pays the compilation cost.

Groovy DSL is like writing in a text editor with no spell-check; the Kotlin DSL is the same document in a word processor that underlines mistakes as you type.

saying these in an interview costs you the question

  • Claiming the Kotlin DSL can do things Groovy cannot (or vice versa) — both use the same API
  • Thinking you set the DSL with a setting or plugin rather than the file extension
  • Believing Groovy scripts are type-checked at edit time
  • Saying .kts is a different build tool, not just a script language

context