skip to content

Groovy to Kotlin DSL Migration

Converting build.gradle to build.gradle.kts file by file: quoting, replacing apply plugin with plugins {}, and rewriting task configuration. A practical question for any team caught mid-migration.

on this pageshow

questions

5

You're starting to migrate a build.gradle to build.gradle.kts. What are the first mechanical changes you make to the file — the filename and the most common syntax fixes?

level: juniorimportance: must knowfreq 55%

answer

  1. rename .gradle -> .gradle.kts
  2. single quotes -> double quotes
  3. parentheses mandatory in Kotlin
  4. named args : -> =
  5. run ./gradlew help to compile scripts

basics

~10 s

Rename build.gradle to build.gradle.kts. Then wrap all strings in double quotes (Kotlin has no single-quote strings), and replace each '=' or Groovy assignment so it follows Kotlin syntax.

solid answer

~40 s

The first step is renaming `build.gradle` to `build.gradle.kts`, which switches Gradle from the Groovy DSL to the Kotlin DSL. Then I fix the mechanical syntax differences: - **Strings:** Groovy allows single quotes (`'foo'`); Kotlin only has double-quoted strings, so every `'...'` becomes `"..."`. Use `"$var"` for interpolation just like Groovy's GString. - **Method calls:** Groovy lets you drop parentheses (`apply plugin: 'java'`); Kotlin requires parentheses and named/typed arguments. - **Assignment:** Groovy properties accept `=` loosely; in Kotlin you assign with `=` to a real property or call a setter, and booleans/collections must be typed correctly. I work incrementally, running `./gradlew help` (or `tasks`) after each chunk so the Kotlin compiler surfaces errors fast. Because the Kotlin DSL is statically compiled, mistakes fail at script-compile time rather than silently.

code

kotlin · 11 lines
kotlin
// Groovy (build.gradle):
//   apply plugin: 'java'
//   sourceCompatibility = 1.8
//   description = 'my app'

// Kotlin (build.gradle.kts):
apply(plugin = "java")
java {
    sourceCompatibility = JavaVersion.VERSION_1_8
}
description = "my app"

go deeper

for a junior

Know the rename and the two big mechanical fixes: double quotes and mandatory parentheses.

for a middle

Explain the incremental file-by-file approach and why help/tasks surfaces errors cheaply.

for a senior

Frame the trade-off: static compilation catches errors up front but is stricter than Groovy's dynamic dispatch.

for a principal

Discuss rollout strategy across a multi-module repo and the team cost/benefit of switching DSLs.

## Why a rename changes everything Gradle picks the DSL **by file extension**. A file named `build.gradle` is compiled as a Groovy script; `build.gradle.kts` is compiled as a Kotlin script. Renaming the file is therefore the single switch that flips the whole language — but it also means every line is now type-checked by the Kotlin compiler, so syntax that Groovy tolerated will now fail at **script-compile time** (before any task runs). ## The mechanical differences you hit first ### 1. Strings Groovy has two string literals: single-quoted plain strings (`'java'`) and double-quoted GStrings that interpolate (`"$name"`). **Kotlin has only double-quoted strings.** So `'java'` becomes `"java"`. Interpolation syntax is the same: `"$version"` or `"${project.name}"`. ### 2. Parentheses are mandatory Groovy allows command-style calls without parentheses: `apply plugin: 'java'` is really `apply(plugin: 'java')`. Kotlin requires the parentheses: `apply(plugin = "java")`. The Groovy `key: value` named-argument syntax becomes Kotlin's `key = value`. ### 3. Assignment vs. method call In Groovy `sourceCompatibility = 1.8` works through dynamic property dispatch. In Kotlin you assign to a typed property or call a setter, and the value must have the right type (e.g. `"1.8"` or `JavaVersion.VERSION_1_8`). ## Incremental, file-by-file workflow The recommended migration is **not** a big-bang rewrite. Convert one file at a time (settings first, then root `build.gradle`, then each subproject), and after each step run a cheap task like: ```bash ./gradlew help ``` `help` forces Gradle to **compile and evaluate** every build script without running real work, so script-compile errors surface immediately and cheaply. Fix, re-run, repeat. ## Why this matters The Kotlin DSL trades Groovy's permissiveness for **static typing and IDE auto-completion**. The migration is mostly mechanical, but the compiler is now your safety net — every quoting or parenthesis slip is caught up front instead of failing deep into a build.

  • Why does running ./gradlew help help during migration?
    It forces Gradle to compile and evaluate all build scripts without doing real build work, so Kotlin script-compile errors surface fast and cheaply after each edit.
  • Why can't you keep single-quoted strings in the Kotlin DSL?
    Kotlin has no single-quote string literal — single quotes denote a Char. All strings must be double-quoted.

saying these in an interview costs you the question

  • Saying you can mix Groovy and Kotlin syntax in one .kts file.
  • Claiming the rename is optional or that Gradle auto-detects DSL from content rather than extension.

context

open as a page

During migration, how do you convert legacy `apply plugin: '...'` lines to the modern `plugins {}` block in Kotlin DSL, and what changes for plugin versions?

level: middleimportance: must knowfreq 50%

basics

~10 s

Replace each apply plugin: 'id' with an entry in a plugins {} block, e.g. id("java"). Core plugins like java or application can use the accessor form. Versions move into the plugins block via version.

open as a page

How does task configuration change when migrating from the Groovy DSL to the Kotlin DSL — for example configuring the `test`, `jar`, or a custom task?

level: middleimportance: must knowfreq 45%

basics

~20 s

Groovy's loose task foo and test { } become typed Kotlin calls. Use tasks.named("test") { ... } to configure an existing task and tasks.register("foo") { ... } to create one, with property assignments using =.

open as a page

What are the most common errors engineers hit when converting build.gradle to build.gradle.kts, and how do you fix each?

level: middleimportance: should knowfreq 40%

basics

~10 s

Typical errors: single quotes (use double), missing parentheses, def instead of val/var, assigning a lazy Property with = instead of .set(...), and using "$buildDir" patterns that are deprecated. Fix each to Kotlin syntax.

open as a page

What is a safe, practical strategy for migrating a large multi-module Groovy build to the Kotlin DSL without breaking the build, and how do you validate each step?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Migrate file by file, not all at once. Gradle lets Groovy and Kotlin scripts coexist across modules. Convert one script, run ./gradlew help or tasks to verify it compiles, commit, then move to the next.

open as a page