Kora project setup kotlin
Skill kora-projects/kora-skills/plugins/kora-v1/skills/kora-project-setup-kotlin
Agent Skills for Kora Framework — compile-time DI for Java/Kotlin backend development.
npx -y skills add kora-projects/kora-skills --skill kora-project-setup-kotlinAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Scaffolds a new Kotlin Kora service with Gradle Kotlin DSL — KSP symbol processors, the kora-parent BOM, the koraBom configuration, jvmToolchain, a @KoraApp interface extending *Module interfaces, and the Gradle wrapper. Use when creating a Kotlin Kora project from scratch, wiring up build.gradle.kts / settings.gradle.kts / gradle.properties, configuring KSP (com.google.devtools.ksp), or splitting a service into Gradle modules with @KoraSubmodule. Use for Kotlin only; for Java use kora-project-setup-java.
SKILL.md
9.9 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
Kora Project Setup — Kotlin
Scaffold a runnable Kotlin Kora service: Gradle Kotlin DSL build, KSP symbol
processors, the kora-parent BOM, and a @KoraApp interface that plugs in Kora
capabilities by extending *Module interfaces.
Pinned versions (match .kora-agent/kora-examples): Kora BOM 1.2.17,
Kotlin 1.9.25, KSP 1.9.25-1.0.20, Gradle 9.5.1, JVM toolchain 21.
Never version individual ru.tinkoff.kora:* artifacts — the BOM aligns them all.
Core principle
Kora generates code at compile time. For Kotlin this runs through KSP (the
com.google.devtools.ksp plugin + the ru.tinkoff.kora:symbol-processors
artifact), not Java's annotationProcessor. Without KSP, nothing is generated
and the build produces no ApplicationGraph. KSP writes generated sources to
build/generated/ksp/main/kotlin — register that directory as a source dir so
IDEs and compilation see it.
Project structure
my-app/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── gradle/wrapper/gradle-wrapper.properties
├── src/main/
│ ├── kotlin/com/example/Application.kt
│ └── resources/application.conf # HOCON config
│ └── resources/logback.xml # logging config
└── src/test/kotlin/com/example/
Quick Start
1. settings.gradle.kts
The foojay-resolver-convention plugin lets the Java toolchain auto-download the
requested JDK instead of relying only on locally installed ones.
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
rootProject.name = "kora-example"
2. build.gradle.kts
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JvmVendorSpec
plugins {
id("application")
kotlin("jvm") version "1.9.25"
id("com.google.devtools.ksp") version "1.9.25-1.0.20"
}
repositories {
mavenCentral()
}
// The koraBom configuration carries the BOM and feeds aligned versions into the
// real configurations. ksp needs it separately because it has its own classpath.
val koraBom: Configuration by configurations.creating
configurations {
ksp.get().extendsFrom(koraBom)
compileOnly.get().extendsFrom(koraBom)
implementation.get().extendsFrom(koraBom)
testImplementation.get().extendsFrom(koraBom)
kspTest.get().extendsFrom(koraBom)
}
dependencies {
koraBom(platform("ru.tinkoff.kora:kora-parent:1.2.17"))
// Mandatory: the Kora symbol processors. Without them nothing is generated.
ksp("ru.tinkoff.kora:symbol-processors")
implementation("ru.tinkoff.kora:http-server-undertow")
implementation("ru.tinkoff.kora:config-hocon")
implementation("ru.tinkoff.kora:json-module")
implementation("ru.tinkoff.kora:logging-logback")
kspTest("ru.tinkoff.kora:symbol-processors")
testImplementation("ru.tinkoff.kora:test-junit5")
}
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(21))
vendor.set(JvmVendorSpec.ADOPTIUM)
}
sourceSets.main { kotlin.srcDir("build/generated/ksp/main/kotlin") }
sourceSets.test { kotlin.srcDir("build/generated/ksp/test/kotlin") }
}
application {
applicationName = "application"
mainClass.set("com.example.ApplicationKt")
applicationDefaultJvmArgs = listOf("-Dfile.encoding=UTF-8")
}
tasks.distTar {
archiveFileName.set("application.tar")
}
tasks.test {
useJUnitPlatform()
}
Full file: assets/build.gradle.kts.template
3. gradle.properties
org.gradle.java.installations.auto-detect=true
org.gradle.java.installations.auto-download=true
# Kotlin 1.9.25 cannot target every recent JDK exactly; warn instead of fail.
kotlin.jvm.target.validation.mode=warning
org.gradle.jvmargs=-Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.caching=true
4. Application.kt
@KoraApp marks the application graph root. Each Kora capability is added by
extending its *Module interface. The ApplicationGraph object is generated by
KSP at compile time, so it does not resolve in the IDE until the first build.
package com.example
import ru.tinkoff.kora.application.graph.KoraApplication
import ru.tinkoff.kora.common.KoraApp
import ru.tinkoff.kora.config.hocon.HoconConfigModule
import ru.tinkoff.kora.http.server.undertow.UndertowHttpServerModule
import ru.tinkoff.kora.json.module.JsonModule
import ru.tinkoff.kora.logging.logback.LogbackModule
@KoraApp
interface Application :
HoconConfigModule,
JsonModule,
LogbackModule,
UndertowHttpServerModule
fun main() {
KoraApplication.run { ApplicationGraph.graph() }
}
Full file: assets/Application.kt.template
5. A first component
Components are registered with @Component; an HTTP controller adds
@HttpController and @HttpRoute. Adapted from
.kora-agent/kora-examples/guides/kotlin/kora-kotlin-guide-getting-started-app.
package com.example
import ru.tinkoff.kora.common.Component
import ru.tinkoff.kora.http.common.HttpMethod
import ru.tinkoff.kora.http.common.annotation.HttpRoute
import ru.tinkoff.kora.http.common.body.HttpBody
import ru.tinkoff.kora.http.server.common.HttpServerResponse
import ru.tinkoff.kora.http.server.common.annotation.HttpController
@Component
@HttpController
class HelloController {
@HttpRoute(method = HttpMethod.GET, path = "/hello")
fun hello(): HttpServerResponse =
HttpServerResponse.of(200, HttpBody.plaintext("Hello, Kora!"))
}
6. application.conf (HOCON)
Keep public traffic and metrics/probes on separate ports.
httpServer {
publicApiHttpPort = 8080
privateApiHttpPort = 8085
telemetry.logging.enabled = true
}
logging.level {
"root": "WARN"
"ru.tinkoff.kora": "INFO"
}
7. Gradle wrapper
gradle/wrapper/gradle-wrapper.properties:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Commands
./gradlew classes # runs KSP; first real validation that the graph builds
./gradlew run # starts the application
./gradlew clean build # full build + tests
./gradlew test # tests
classes is a meaningful check in Kora: it runs the symbol processors, so it
verifies not only Kotlin syntax but that the application graph can be assembled.
When to use vs NOT
| Use this skill when | Do NOT use when |
|---|---|
| Starting a new Kotlin Kora service | Project is Java → use kora-project-setup-java |
Wiring build.gradle.kts, KSP, the BOM, the wrapper | Adding modules to an existing Kora app → kora-project-dependencies |
Splitting a service into Gradle modules with @KoraSubmodule | Configuring HOCON details → kora-config-hocon |
Common pitfalls
| Symptom | Cause | Fix |
|---|---|---|
ApplicationGraph unresolved | KSP never ran | Run ./gradlew classes; ensure the ksp(...) dependency and the KSP plugin are present |
| IDE cannot see generated classes | KSP output dir not a source dir | Add sourceSets.main { kotlin.srcDir("build/generated/ksp/main/kotlin") } |
| "Required dependency not found" | A *Module not extended, or @Component missing | Extend the module on @KoraApp; annotate the class with @Component |
| Version conflicts on Kora artifacts | A ru.tinkoff.kora:* dep pinned manually | Remove the explicit version; let the BOM align it |
Build hangs after clean | Stale Gradle daemon | ./gradlew --stop, then retry |
Multi-module / @KoraSubmodule
Most services are a single module. To split across Gradle modules with
@KoraSubmodule feature modules aggregated by a @KoraApp app module, see
references/multi-module-reference.md.
Assets
| File | Description |
|---|---|
assets/build.gradle.kts.template | Single-module Kotlin build config |
assets/settings.gradle.kts.template | Settings with foojay toolchain resolver |
assets/Application.kt.template | @KoraApp root + main() |
assets/gradle.properties | Gradle/Kotlin properties |
assets/gradle-wrapper.properties | Gradle wrapper config |
Next steps
kora-project-dependencies— add modules (HTTP, Database, Kafka, ...)kora-config-hocon— typed@ConfigSourceconfigurationkora-di-compile— compile-time DI patternskora-testing-junit-kotlin—@KoraAppTestcomponent tests
References
| Document | Description |
|---|---|
references/multi-module-reference.md | Gradle multi-module + @KoraSubmodule setup |
bom-usage-reference.md | BOM setup details |
compatibility-matrix.md | Version compatibility |
core-modules-reference.md | Core modules catalogue |
What ships with it: 7 files
14.0 KB alongside SKILL.md
assets/
evals/
- evals.json4.9 KB