Kotlin Help

Gradle

In order to build a Kotlin project with Gradle, you should apply the Kotlin Gradle plugin to your project and configure dependencies.

Plugin and versions

Apply the Kotlin Gradle plugin by using the Gradle plugins DSL.

The Kotlin Gradle plugin and kotlin-multiplatform plugin 1.5.21 require Gradle 6.1 or later.

plugins { id 'org.jetbrains.kotlin.<...>' version '1.5.21' }
plugins { kotlin("<...>") version "1.5.21" }

The placeholder <...> should be replaced with one of the plugin names that can be found in further sections.

Targeting multiple platforms

Projects targeting multiple platforms, called multiplatform projects, require the kotlin-multiplatform plugin. Learn more about the plugin.

plugins { id 'org.jetbrains.kotlin.multiplatform' version '1.5.21' }
plugins { kotlin("multiplatform") version "1.5.21" }

Targeting the JVM

To target the JVM, apply the Kotlin JVM plugin.

plugins { id "org.jetbrains.kotlin.jvm" version "1.5.21" }
plugins { kotlin("jvm") version "1.5.21" }

The version should be literal in this block, and it cannot be applied from another build script.

Alternatively, you can use the older apply plugin approach:

apply plugin: 'kotlin'

It's not recommended that you apply Kotlin plugins with apply in Gradle Kotlin DSL – see why.

Kotlin and Java sources

Kotlin sources can be stored with Java sources in the same folder, or placed to different folders. The default convention is using different folders:

project - src - main (root) - kotlin - java

The corresponding sourceSets property should be updated if not using the default convention:

sourceSets { main.kotlin.srcDirs += 'src/main/myKotlin' main.java.srcDirs += 'src/main/myJava' }
sourceSets.main { java.srcDirs("src/main/myJava", "src/main/myKotlin") }

Targeting JavaScript

When targeting only JavaScript, use the kotlin-js plugin. Learn more

plugins { id 'org.jetbrains.kotlin.js' version '1.5.21' }
plugins { kotlin("js") version "1.5.21" }

Kotlin and Java sources for JavaScript

This plugin only works for Kotlin files so it is recommended that you keep Kotlin and Java files separately (in case the project contains Java files). If you don't store them separately , specify the source folder in the sourceSets block:

kotlin { sourceSets { main.kotlin.srcDirs += 'src/main/myKotlin' } }
kotlin { sourceSets["main"].apply { kotlin.srcDir("src/main/myKotlin") } }

Targeting Android

It's recommended that you use Android Studio for creating Android applications. Learn how to use Android Gradle plugin.

Configuring dependencies

To add a dependency on a library, set the dependency of the required type (for example, implementation) in the dependencies block of the source sets DSL.

kotlin { sourceSets { commonMain { dependencies { implementation 'com.example:my-library:1.0' } } } }
kotlin { sourceSets { val commonMain by getting { dependencies { implementation("com.example:my-library:1.0") } } } }

Alternatively, you can set dependencies at the top level.

Dependency types

Choose the dependency type based on your requirements.

TypeDescriptionWhen to use
apiUsed both during compilation and at runtime and is exported to library consumers.If any type from a dependency is used in the public API of the current module, use an api dependency.
implementationUsed during compilation and at runtime for the current module, but is not exposed for compilation of other modules depending on the one with the `implementation` dependency.

Use for dependencies needed for the internal logic of a module.

If a module is an endpoint application which is not published, use implementation dependencies instead of api dependencies.

compileOnlyUsed for compilation of the current module and is not available at runtime nor during compilation of other modules.Use for APIs which have a third-party implementation available at runtime.
runtimeOnlyAvailable at runtime but is not visible during compilation of any module.

Dependency on the standard library

A dependency on a standard library (stdlib) in each source set is added automatically. The version of the standard library is the same as the version of the Kotlin Gradle plugin.

For platform-specific source sets, the corresponding platform-specific variant of the library is used, while a common standard library is added to the rest. The Kotlin Gradle plugin will select the appropriate JVM standard library depending on the kotlinOptions.jvmTarget compiler option of your Gradle build script.

If you declare a standard library dependency explicitly (for example, if you need a different version), the Kotlin Gradle plugin won’t override it or add a second standard library.

If you do not need a standard library at all, you can add the opt-out option to the gradle.properties:

kotlin.stdlib.default.dependency=false

Set dependencies on test libraries

The kotlin.test API is available to test Kotlin projects on all supported platforms. Add the dependency kotlin-test to the commonTest source set, and the Gradle plugin will infer the corresponding test dependencies for each test source set:

  • kotlin-test-common and kotlin-test-annotations-common for common source sets

  • kotlin-test-junit for JVM source sets

  • kotlin-test-js for Kotlin/JS source sets

Kotlin/Native targets do not require additional test dependencies, and the kotlin.test API implementations are built-in.

kotlin { sourceSets { commonTest { dependencies { implementation kotlin("test") // This brings all the platform dependencies automatically } } } }
kotlin { sourceSets { val commonTest by getting { dependencies { implementation(kotlin("test")) // This brings all the platform dependencies automatically } } } }

You can use the kotlin-test dependency in any shared or platform-specific source set as well.

For Kotlin/JVM, Gradle uses JUnit 4 by default. Therefore, the kotlin("test") dependency resolves to the variant for JUnit 4, namely kotlin-test-junit.

You can choose JUnit 5 or TestNG by calling useJUnitPlatform() or useTestNG() in the test task of your build script. The following example is for an MPP project:

kotlin { jvm { testRuns["test"].executionTask.configure { useJUnitPlatform() } } sourceSets { commonTest { dependencies { implementation kotlin("test") } } } }
kotlin { jvm { testRuns["test"].executionTask.configure { useJUnitPlatform() } } sourceSets { val commonTest by getting { dependencies { implementation(kotlin("test")) } } } }

The following example is for a JVM project:

dependencies { testImplementation 'org.jetbrains.kotlin:kotlin-test' } test { useTestNG() }
dependencies { testImplementation(kotlin("test")) } tasks { test { useTestNG() } }

Learn how to test code using JUnit on the JVM.

If you need to use a different JVM test framework, disable automatic testing framework selection by adding the line kotlin.test.infer.jvm.variant=false to the project’s gradle.properties. Once you do this, add the framework as a Gradle dependency.

If you had used a variant of kotlin("test") in your build script explicitly and project build stopped working with a conflict on capability, see this issue in the Compatibility Guide.

Set a dependency on a kotlinx library

If you use a kotlinx library and need a platform-specific dependency, you can use platform-specific variants of libraries with suffixes such as -jvm or -js, for example, kotlinx-coroutines-core-jvm. You can also use the library base artifact name instead – kotlinx-coroutines-core.

kotlin { sourceSets { jvmMain { dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.1' } } } }
kotlin { sourceSets { val jvmMain by getting { dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.1") } } } }

If you use a multiplatform library and need to depend on the shared code, set the dependency only once in the shared source set. Use the library base artifact name, such as kotlinx-coroutines-core or ktor-client-core.

kotlin { sourceSets { commonMain { dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1' } } } }
kotlin { sourceSets { val commonMain by getting { dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1") } } } }

Set dependencies at the top level

Alternatively, you can specify the dependencies at the top level with the configuration names following the pattern <sourceSetName><DependencyType>. This is helpful for some Gradle built-in dependencies, like gradleApi(), localGroovy(), or gradleTestKit(), which are not available in the source sets dependency DSL.

dependencies { commonMainImplementation 'com.example:my-library:1.0' }
dependencies { "commonMainImplementation"("com.example:my-library:1.0") }

Annotation processing

Kotlin supports annotation processing via the Kotlin annotation processing tool kapt.

Incremental compilation

The Kotlin Gradle plugin supports incremental compilation. Incremental compilation tracks changes of source files between builds so only files affected by these changes would be compiled.

Incremental compilation is supported for Kotlin/JVM and Kotlin/JS projects and is enabled by default.

There are several ways to switch off incremental compilation:

  • kotlin.incremental=false for Kotlin/JVM.

  • kotlin.incremental.js=false for Kotlin/JS projects.

  • As the command line parameter, use -Pkotlin.incremental=false or -Pkotlin.incremental.js=false for Kotlin/JVM and Kotlin/JS projects respectively.

    Note that in this case the parameter should be added to each subsequent build, and any build with disabled incremental compilation invalidates incremental caches.

Note that the first build isn't incremental in any case.

Gradle build cache support

The Kotlin plugin supports Gradle build cache that stores the build outputs for reuse in future builds.

To disable the caching for all Kotlin tasks, set the system property flag kotlin.caching.enabled to false (run the build with the argument -Dkotlin.caching.enabled=false).

If you use kapt, note that the kapt annotation processing tasks are not cached by default. However, you can enable caching for them manually.

Gradle configuration cache support

The Kotlin plugin supports Gradle configuration cache, which speeds up the build process by reusing the results of the configuration phase.

See the Gradle documentation to learn how to enable the configuration cache. Once you enable the configuration cache feature, the Kotlin Gradle plugin will start using it.

Compiler options

To specify additional compilation options, use the kotlinOptions property of a Kotlin compilation task.

When targeting the JVM, the tasks are called compileKotlin for production code and compileTestKotlin for test code. The tasks for custom source sets are called accordingly to the compile<Name>Kotlin pattern.

The names of the tasks in Android Projects contain the build variant names and follow the pattern compile<BuildVariant>Kotlin, for example, compileDebugKotlin, compileReleaseUnitTestKotlin.

When targeting JavaScript, the tasks are called compileKotlinJs and compileTestKotlinJs respectively, and compile<Name>KotlinJs for custom source sets.

To configure a single task, use its name. Examples:

compileKotlin { kotlinOptions.suppressWarnings = true } //or compileKotlin { kotlinOptions { suppressWarnings = true } }
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile // ... val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions.suppressWarnings = true

Note that with Gradle Kotlin DSL, you should get the task from the project's tasks first.

Use the types Kotlin2JsCompile and KotlinCompileCommon for the JS and Common targets, accordingly.

It is also possible to configure all Kotlin compilation tasks in the project:

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { /*...*/ } }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach { kotlinOptions { /*...*/ } }

The complete list of options for the Gradle tasks is the following:

Attributes common for JVM, JS, and JS DCE

NameDescriptionPossible valuesDefault value
allWarningsAsErrorsReport an error if there are any warningsfalse
suppressWarningsGenerate no warningsfalse
verboseEnable verbose logging outputfalse
freeCompilerArgsA list of additional compiler arguments[]

Attributes common for JVM and JS

NameDescriptionPossible valuesDefault value
apiVersionAllow using declarations only from the specified version of bundled libraries"1.3" (DEPRECATED), "1.4", "1.5", "1.6" (EXPERIMENTAL)
languageVersionProvide source compatibility with the specified version of Kotlin"1.3" (DEPRECATED), "1.4", "1.5", "1.6" (EXPERIMENTAL)

Attributes specific for JVM

NameDescriptionPossible valuesDefault value
javaParametersGenerate metadata for Java 1.8 reflection on method parametersfalse
jdkHomeInclude a custom JDK from the specified location into the classpath instead of the default JAVA_HOME
jvmTargetTarget version of the generated JVM bytecode"1.6" (DEPRECATED), "1.8", "9", "10", "11", "12", "13", "14", "15", "16""1.8"
noJdkDon't automatically include the Java runtime into the classpathfalse
useOldBackendUse the old JVM backendfalse

Attributes specific for JS

NameDescriptionPossible valuesDefault value
friendModulesDisabledDisable internal declaration exportfalse
mainDefine whether the main function should be called upon execution"call", "noCall""call"
metaInfoGenerate .meta.js and .kjsm files with metadata. Use to create a librarytrue
moduleKindThe kind of JS module generated by the compiler"umd", "commonjs", "amd", "plain""umd"
noStdlibDon't automatically include the default Kotlin/JS stdlib into compilation dependenciestrue
outputFileDestination *.js file for the compilation result"<buildDir>/js/packages/<project.name>/kotlin/<project.name>.js"
sourceMapGenerate source maptrue
sourceMapEmbedSourcesEmbed source files into source map"never", "always", "inlining"
sourceMapPrefixAdd the specified prefix to paths in the source map
targetGenerate JS files for specific ECMA version"v5""v5"
typedArraysTranslate primitive arrays to JS typed arraystrue

Generating documentation

To generate documentation for Kotlin projects, use Dokka; please refer to the Dokka README for configuration instructions. Dokka supports mixed-language projects and can generate output in multiple formats, including standard JavaDoc.

OSGi

For OSGi support see the Kotlin OSGi page.

Using Gradle Kotlin DSL

When using Gradle Kotlin DSL, apply the Kotlin plugins using the plugins { ... } block. If you apply them with apply { plugin(...) } instead, you may encounter unresolved references to the extensions generated by Gradle Kotlin DSL. To resolve that, you can comment out the erroneous usages, run the Gradle task kotlinDslAccessorsSnapshot, then uncomment the usages back and rerun the build or reimport the project into the IDE.

Last modified: 27 July 2021