---
title: "From Groovy to Kotlin DSL: Migrating Gradle Build Scripts"
description: "Migrating Gradle build scripts from Groovy to Kotlin DSL. Step-by-step guide with code examples for Spring Boot projects."
keywords: "Gradle, Kotlin DSL, Groovy, Migration, Build, Spring Boot"
url: "https://encircle360.com/en/blog/gradle-kotlin-dsl-migration"
language: "en"
type: "article"
date: "2022-05-09"
reading_time_minutes: 6
categories: ["Software Engineering"]
image: "https://cms.encircle360.com/assets/3928d0bb-eb7e-40b9-8f93-4fd2863e064c?width=1200&quality=80&format=webp"
author:
  name: "Patrick Hütter"
  role: "Founder & Software Architect"
  company: "encircle360 GmbH"
  url: "https://encircle360.com/en/blog?author=patrick-huetter"
  linkedin: "https://www.linkedin.com/in/patrickhuetter/"
publisher:
  name: "encircle360 GmbH"
  url: "https://encircle360.com"
  email: "hello@encircle360.com"
  phone: "+49 214 736999-80"
  address: "Petersbergstraße 72, 51375 Leverkusen, DE"
  linkedin: "https://www.linkedin.com/company/encircle360"
alternates:
  de: "https://encircle360.com/de/blog/gradle-kotlin-dsl-migration"
citation: "Patrick Hütter (encircle360 GmbH): \"From Groovy to Kotlin DSL: Migrating Gradle Build Scripts\", 2022-05-09, https://encircle360.com/en/blog/gradle-kotlin-dsl-migration"
---

# From Groovy to Kotlin DSL: Migrating Gradle Build Scripts

_By **Patrick Hütter**, Founder & Software Architect at [encircle360 GmbH](https://encircle360.com) · 9 May 2022 · 6 min read · Categories: Software Engineering_

> The Gradle Kotlin DSL brings type safety and real IDE support to build scripts. We show how to successfully migrate from Groovy and what to watch out for.

# From Groovy to Kotlin DSL: Migrating Gradle Build Scripts

We have been using Gradle as the build tool for our JVM projects since 2018 -- starting with the [switch from Maven to Gradle](https://encircle360.com/blog/gradle-instead-of-maven), later explored further in our article on [Groovy as a DSL language in Gradle](https://encircle360.com/blog/groovy-gradle-dsl-power). In parallel, Kotlin has evolved over the years into our preferred language for Spring Boot backends, as we described in our posts on [Kotlin in the Spring ecosystem](https://encircle360.com/blog/kotlin-spring-boot-getting-started) and the [practical experience report](https://encircle360.com/blog/kotlin-spring-boot-practical-experience). Nevertheless, we kept our build scripts in Groovy for a long time. We have now changed that.

## Why Switch at All?

Groovy in Gradle works. We have proven that over the years. But there is a problem that becomes increasingly apparent with growing projects: the IDE does not know what is happening in a `build.gradle`. Groovy's dynamic typing, which we described as a strength in [our Groovy article](https://encircle360.com/blog/groovy-gradle-dsl-power), becomes a weakness when editing build scripts. Auto-completion works at best rudimentarily, refactoring support is practically nonexistent, and errors only surface at runtime -- meaning during the next `gradle build`.

The Kotlin DSL solves exactly this problem. Build scripts are statically typed, IntelliJ IDEA knows every type, every method, every property. You get real auto-completion, can navigate into the Gradle API via Cmd+Click, and see errors immediately as red underlines. For teams that already write Kotlin, there is an additional benefit: you have a unified language for production code and build logic.

With Gradle 7.x, the Kotlin DSL has matured. The performance issues of earlier versions have been resolved, IDE integration in IntelliJ IDEA works reliably, and the entire Gradle documentation provides examples in both variants. There is no longer a good reason to stay with Groovy when building Kotlin projects.

## The Migration Strategy

Gradle allows mixing Groovy and Kotlin DSL scripts within a single build. This is the key to a low-risk migration. You do not have to convert everything at once but can proceed file by file.

Our order:

1.  Migrate `settings.gradle` to `settings.gradle.kts`
2.  Convert the root `build.gradle` to `build.gradle.kts`
3.  Migrate subproject build scripts individually

The step is the same each time: rename the file, adjust the syntax, run the build, test. Thanks to the ability to mix scripts, you can deploy after each step without breaking anything.

## The Most Important Syntax Differences

### Strings: Double Instead of Single Quotes

In Groovy, both single and double quotes are allowed for strings. In Kotlin, only double quotes exist. This affects practically every line in the build script.

**Groovy:**

```groovy
group = 'com.encircle360'
version = '1.0.0-SNAPSHOT'
```

**Kotlin DSL:**

```kotlin
group = "com.encircle360"
version = "1.0.0-SNAPSHOT"
```

### Plugins Block

The plugins block changes syntactically because Kotlin requires parentheses for method calls and does not allow implicit method calls without them.

**Groovy:**

```groovy
plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'org.jetbrains.kotlin.jvm' version '1.6.21'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.6.21'
}
```

**Kotlin DSL:**

```kotlin
plugins {
    java
    id("org.springframework.boot") version "2.7.0"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    id("org.jetbrains.kotlin.jvm") version "1.6.21"
    id("org.jetbrains.kotlin.plugin.spring") version "1.6.21"
}
```

For standard plugins like `java`, the Kotlin DSL provides accessor properties that can be used directly without `id()`. This is shorter and type-safe.

### Assignments with the = Operator

In Groovy, you can assign properties with a space -- which is actually a method call. In Kotlin, the assignment operator `=` must be used.

**Groovy:**

```groovy
sourceCompatibility = '17'
targetCompatibility = '17'

springBoot {
    mainClass = 'com.encircle360.app.Application'
}
```

**Kotlin DSL:**

```kotlin
java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

springBoot {
    mainClass.set("com.encircle360.app.Application")
}
```

This shows another advantage of the Kotlin DSL: the assignment of `sourceCompatibility` uses the `JavaVersion` enum instead of a string. Errors like `sourceCompatibility = '1.17'` are caught immediately.

### Dependencies

For dependencies, parentheses and double quotes become mandatory. Additionally, the Groovy shorthand of omitting parentheses in method calls is no longer available.

**Groovy:**

```groovy
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    runtimeOnly 'org.postgresql:postgresql'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

**Kotlin DSL:**

```kotlin
dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    runtimeOnly("org.postgresql:postgresql")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}
```

The difference may seem cosmetic but has a tangible benefit: IntelliJ recognizes the dependency coordinates as strings in a method call and can apply code inspections to them.

### Custom Tasks

Task definitions change the most noticeably. The Groovy syntax with `task taskName(type: TaskType)` no longer exists. Instead, you use `tasks.register<TaskType>("taskName")`.

**Groovy:**

```groovy
task cleanBuildDir(type: Delete) {
    delete 'build/generated'
}

task printVersion {
    doLast {
        println "Version: ${project.version}"
    }
}
```

**Kotlin DSL:**

```kotlin
tasks.register<Delete>("cleanBuildDir") {
    delete("build/generated")
}

tasks.register("printVersion") {
    doLast {
        println("Version: ${project.version}")
    }
}
```

The generic type specification `<Delete>` immediately makes clear which task type is being used. In the IDE, this gives you auto-completion for all properties and methods of the respective task type.

### Extra Properties Instead of ext

In Groovy, the `ext` block is commonly used to define project-wide variables. The Kotlin DSL provides the `extra` mechanism for this purpose.

**Groovy:**

```groovy
ext {
    springCloudVersion = '2021.0.3'
    kotlinVersion = '1.6.21'
}
```

**Kotlin DSL:**

```kotlin
val springCloudVersion by extra("2021.0.3")
val kotlinVersion by extra("1.6.21")
```

In subprojects, you access these with `val springCloudVersion: String by rootProject.extra`. This is somewhat more verbose than in Groovy, but type-safe -- the variable has a concrete type, and the compiler verifies it.

## Pitfalls in Practice

**Buildscript block**: If you still use a `buildscript` block for older plugin repositories, you need to apply the same syntax changes there as well. Better yet, take the opportunity to replace the `buildscript` block entirely with the `plugins` block combined with `pluginManagement` in `settings.gradle.kts`.

**Groovy plugins**: Some older Gradle plugins only expose their configuration as Groovy extensions. In rare cases, the configuration does not work directly in the Kotlin DSL, and you need to fall back to `withGroovyBuilder` or `the<ExtensionType>()`. With current plugins like Spring Boot, Kotlin, or Flyway, we had no issues.

**String interpolation**: Groovy uses `${variable}` only in double-quoted strings; in single-quoted strings, variables are not resolved. Since Kotlin always uses double quotes, `$variable` and `${expression}` always work. But be careful: if you need `$` as a literal character, you must escape it.

**Performance on first build**: After renaming to `.gradle.kts`, the first build takes a bit longer because Gradle compiles the script for the first time. After that, the script cache kicks in, and build times are comparable to Groovy.

## Our Conclusion

We performed the migration in an existing multi-module project with six subprojects. In total, the conversion took about half a day, spread across multiple merge requests. The biggest time investment is not in the syntax conversion itself -- that is mechanical -- but in testing whether all build variants, profiles, and CI pipelines continue to work.

The result was worth it. IDE support is noticeably better, errors in build scripts are caught earlier, and new team members who know Kotlin find their way around immediately. For projects that already use Kotlin as their development language, the migration is a clear recommendation. The effort is manageable, and the day-to-day benefits are lasting.

---

## About the author

**Patrick Hütter** — Founder & Software Architect, encircle360 GmbH

Software architect, engineer and entrepreneur. Patrick has been building products and platforms for over a decade — from enterprise backends and cloud-native infrastructure to AI-powered applications. As founder of encircle360, he combines deep technical expertise with entrepreneurial vision, driving open source projects that create real impact.

[LinkedIn](https://www.linkedin.com/in/patrickhuetter/) · hello@encircle360.com

---

## About encircle360 GmbH

encircle360 is an owner-led software and AI company based in Leverkusen, Germany. We are a partner for professional software development and digital transformation — from discovery & strategy through product development and artificial intelligence to venture building.

- **Services:** [Discovery & Strategy](https://encircle360.com/en/services/discovery-strategy) · [Product Development](https://encircle360.com/en/services/product-development) · [Venture Building](https://encircle360.com/en/services/venture-building) · [Artificial Intelligence](https://encircle360.com/en/services/artificial-intelligence)
- **Contact:** hello@encircle360.com · +49 214 736999-80 · [encircle360.com](https://encircle360.com)
- **Address:** Petersbergstraße 72, 51375 Leverkusen, Germany
- **Social:** [LinkedIn](https://www.linkedin.com/company/encircle360) · [Xing](https://www.xing.com/pages/encircle360gmbh) · [X](https://x.com/encircle360com)

Source: [From Groovy to Kotlin DSL: Migrating Gradle Build Scripts](https://encircle360.com/en/blog/gradle-kotlin-dsl-migration) — © encircle360 GmbH. When using or summarising this content, please credit encircle360 GmbH and link back to https://encircle360.com/en/blog/gradle-kotlin-dsl-migration.

Every page of this website is also available as Markdown: append `.md` to the URL or send the header `Accept: text/markdown`. Index for agents: https://encircle360.com/llms.txt
