# Gradle Patterns

> When to activate: Gradle, Kotlin DSL, build.gradle.kts, multi-module, version catalog, gradle plugins, build optimization, task configuration

- Skill: `mattakushi432/gradle-patterns` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattakushi432/gradle-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattakushi432/gradle-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: Mattakushi432 (https://skillmd.com/u/mattakushi432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mattakushi432/gradle-patterns

---

# Gradle Kotlin DSL Patterns

## Root Build File (Multi-Module)

```kotlin
// settings.gradle.kts
rootProject.name = "my-app"
include(":core", ":api", ":worker", ":shared")

dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
    versionCatalogs {
        create("libs") { from(files("gradle/libs.versions.toml")) }
    }
}
```

## Version Catalog (gradle/libs.versions.toml)

```toml
[versions]
kotlin = "2.0.0"
spring-boot = "3.3.0"
coroutines = "1.8.1"
ktor = "2.3.12"
kotest = "5.9.1"

[libraries]
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring-boot" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotest-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }

[bundles]
ktor-server = ["ktor-server-core", "ktor-server-netty", "ktor-server-content-negotiation"]
testing = ["kotest-runner", "kotest-assertions", "mockk"]

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
```

## Module build.gradle.kts

```kotlin
plugins {
    alias(libs.plugins.kotlin.jvm)
    alias(libs.plugins.spring.boot)
    kotlin("plugin.spring") version libs.versions.kotlin.get()
}

dependencies {
    implementation(project(":shared"))
    implementation(libs.spring.boot.starter.web)
    implementation(libs.kotlinx.coroutines.core)
    implementation(libs.bundles.ktor.server)

    testImplementation(libs.bundles.testing)
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

kotlin {
    jvmToolchain(21)
    compilerOptions {
        freeCompilerArgs.addAll("-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn")
    }
}

tasks.test {
    useJUnitPlatform()
    maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
}
```

## Custom Task

```kotlin
tasks.register<Exec>("generateOpenApi") {
    group = "documentation"
    description = "Generate OpenAPI spec from running server"
    commandLine("curl", "-o", "docs/openapi.yaml", "http://localhost:8080/v3/api-docs.yaml")
    dependsOn(tasks.bootRun)
}

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

// Task dependency
tasks.named("build") { dependsOn("generateOpenApi") }
```

## Build Optimization

```kotlin
// gradle.properties
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.configuration-cache=true
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError

// Exclude test tasks from full build when not needed
tasks.withType<Test> {
    onlyIf { System.getenv("SKIP_TESTS") == null }
}

// Avoid rerunning if inputs unchanged
tasks.register("generateSources") {
    inputs.dir("src/main/proto")
    outputs.dir("build/generated/source/proto")
    doLast { /* generation logic */ }
}
```

## Convention Plugin (buildSrc)

```kotlin
// buildSrc/src/main/kotlin/kotlin-library.gradle.kts
plugins {
    kotlin("jvm")
    id("jacoco")
}

kotlin { jvmToolchain(21) }

tasks.test {
    useJUnitPlatform()
    finalizedBy(tasks.jacocoTestReport)
}

tasks.jacocoTestReport {
    reports { xml.required = true }
}
```

## Key Rules
- Use version catalogs (`libs.versions.toml`) — single source of truth for dependency versions
- `buildSrc` convention plugins eliminate copy-paste across modules
- Enable `configuration-cache` and `parallel` in `gradle.properties` for faster builds
- Use `alias(libs.plugins.xxx)` syntax — it's type-safe and IDE-navigable
- `jvmToolchain(21)` ensures consistent JVM version across all developers without system-level setup

