Official Gradle plugin for the Kotlin programming language that provides comprehensive build support for Kotlin projects including compilation, multiplatform development, Android integration, and native development capabilities
—
This document covers specialized support for Kotlin/JS and Kotlin/WebAssembly compilation with browser, Node.js, and other runtime targets.
import org.jetbrains.kotlin.gradle.ExperimentalWasmDslinterface KotlinJsTarget : KotlinTarget {
val irTarget: Boolean
fun browser(configure: KotlinJsBrowserDsl.() -> Unit = {})
fun nodejs(configure: KotlinJsNodeDsl.() -> Unit = {})
val testRuns: NamedDomainObjectContainer<KotlinTargetTestRun<*>>
val compilations: NamedDomainObjectContainer<KotlinJsCompilation>
}Basic JS Target Setup:
kotlin {
js(IR) { // Use IR compiler (recommended)
browser {
webpackTask {
outputFileName = "app.js"
sourceMaps = true
}
distribution {
outputDirectory = File("$projectDir/web")
}
}
nodejs {
runTask {
args.add("--experimental-modules")
}
}
}
}interface KotlinJsBrowserDsl {
fun webpackTask(configure: KotlinWebpack.() -> Unit)
fun runTask(configure: KotlinWebpack.() -> Unit)
fun testTask(configure: KotlinWebpack.() -> Unit)
val distribution: Distribution
}
interface KotlinWebpack : Task {
var outputFileName: String
var sourceMaps: Boolean
var devServer: KotlinWebpackDevServer?
val entry: RegularFileProperty
val destinationDirectory: DirectoryProperty
val configDirectory: DirectoryProperty
}
interface KotlinWebpackDevServer {
var enabled: Boolean
var port: Int
var proxy: MutableMap<String, String>
var static: MutableList<String>
}Advanced Browser Configuration:
kotlin {
js(IR) {
browser {
webpackTask {
outputFileName = "myapp.js"
sourceMaps = true
devServer = KotlinWebpackDevServer().apply {
enabled = true
port = 3000
proxy.apply {
put("/api", "http://localhost:8080")
}
static.apply {
add("static")
add("resources")
}
}
}
runTask {
sourceMaps = false
devtool = "eval-cheap-source-map"
}
testTask {
useKarma {
useChromeHeadless()
useFirefoxHeadless()
}
}
distribution {
outputDirectory = File("$buildDir/distributions")
}
}
}
}interface KotlinJsNodeDsl {
fun runTask(configure: NodeJsExec.() -> Unit)
fun testTask(configure: NodeJsExec.() -> Unit)
}
interface NodeJsExec : Exec {
val args: MutableList<String>
val environment: MutableMap<String, String>
val ignoreExitValue: Boolean
}Node.js Configuration Example:
kotlin {
js(IR) {
nodejs {
runTask {
args.addAll("--experimental-modules", "--trace-warnings")
environment["NODE_ENV"] = "development"
}
testTask {
args.add("--experimental-vm-modules")
environment["NODE_OPTIONS"] = "--max-old-space-size=4096"
}
}
}
}@ExperimentalWasmDsl
interface KotlinWasmJsTarget : KotlinTarget {
fun browser(configure: KotlinWasmJsBrowserDsl.() -> Unit = {})
fun nodejs(configure: KotlinWasmJsNodeDsl.() -> Unit = {})
fun d8(configure: KotlinWasmJsD8Dsl.() -> Unit = {})
}
interface KotlinWasmJsBrowserDsl {
fun webpackTask(configure: KotlinWebpack.() -> Unit)
fun runTask(configure: KotlinWebpack.() -> Unit)
fun testTask(configure: KotlinWebpack.() -> Unit)
}WASM-JS Configuration:
kotlin {
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser {
webpackTask {
outputFileName = "app.wasm.js"
sourceMaps = true
}
}
nodejs {
runTask {
args.add("--experimental-wasm-modules")
}
}
d8 {
// V8 shell configuration for testing
}
}
}@ExperimentalWasmDsl
interface KotlinWasmWasiTarget : KotlinTarget {
fun nodejs(configure: KotlinWasmWasiNodeDsl.() -> Unit = {})
}WASM-WASI Configuration:
kotlin {
wasmWasi {
nodejs {
runTask {
args.addAll("--experimental-wasi-unstable-preview1", "--experimental-wasm-bigint")
}
}
}
}// NPM dependency declaration
fun npm(name: String, version: String): NpmDependency
fun npm(name: String, version: String, generateExternals: Boolean): NpmDependency
fun devNpm(name: String, version: String): NpmDependency
fun peerNpm(name: String, version: String): NpmDependency
fun optionalNpm(name: String, version: String): NpmDependencyNPM Usage Example:
kotlin {
js(IR) {
browser()
nodejs()
}
sourceSets {
jsMain {
dependencies {
// Kotlin wrappers
implementation("org.jetbrains.kotlin-wrappers:kotlin-react:18.2.0-pre.467")
implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:18.2.0-pre.467")
// NPM packages
implementation(npm("react", "18.2.0"))
implementation(npm("react-dom", "18.2.0"))
implementation(npm("lodash", "4.17.21"))
// Development dependencies
implementation(devNpm("webpack", "5.88.0"))
implementation(devNpm("webpack-dev-server", "4.15.1"))
}
}
}
}// Configure Yarn in root project
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().apply {
yarnLockMismatchReport = org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport.WARNING
reportNewYarnLock = false
yarnLockAutoReplace = false
}
}interface D8RootExtension {
val version: Property<String>
val downloadBaseUrl: Property<String>
val installationDirectory: DirectoryProperty
}
interface D8EnvSpec {
val version: String
val downloadUrl: String
val executablePath: String
}D8 Setup:
// Configure D8 for WASM testing
rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.wasm.d8.D8RootExtension> {
version.set("11.4.183")
downloadBaseUrl.set("https://storage.googleapis.com/chromium-v8/official/canary")
}
kotlin {
wasmJs {
d8 {
// D8-specific configuration
}
}
}abstract class D8Exec : AbstractExecTask<D8Exec> {
abstract val inputFileProperty: RegularFileProperty
abstract val outputFileProperty: RegularFileProperty
abstract val d8Args: ListProperty<String>
}
abstract class D8SetupTask : DefaultTask() {
abstract val d8EnvSpec: Property<D8EnvSpec>
abstract val destinationDirectory: DirectoryProperty
}enum class KotlinJsModuleKind {
MODULE_AMD, // AMD modules (require.js)
MODULE_COMMONJS, // CommonJS modules (Node.js)
MODULE_PLAIN, // Plain JS (global scope)
MODULE_UMD, // Universal Module Definition
MODULE_ES // ES6 modules
}Module Configuration:
kotlin {
js(IR) {
compilations.all {
compilerOptions.configure {
moduleKind.set(KotlinJsModuleKind.MODULE_ES)
target.set("es2015")
sourceMap.set(true)
sourceMapEmbedSources.set(org.jetbrains.kotlin.gradle.dsl.SourceMapEmbedSources.SOURCE_MAP_SOURCE_CONTENT_ALWAYS)
}
}
}
}// Karma test configuration
testTask {
useKarma {
useChromeHeadless()
useFirefoxHeadless()
webpackConfig.cssSupport {
enabled.set(true)
}
webpackConfig.bundleAnalyzerReportDir = file("$buildDir/reports/webpack")
}
}kotlin {
js(IR) {
nodejs {
testTask {
args.addAll(
"--experimental-vm-modules",
"--experimental-wasm-modules"
)
environment["NODE_OPTIONS"] = "--max-old-space-size=4096"
environment["NODE_ENV"] = "test"
}
}
}
}interface Distribution {
var outputDirectory: File
var name: String
fun from(source: Any)
fun exclude(pattern: String)
fun include(pattern: String)
}Distribution Configuration:
kotlin {
js(IR) {
browser {
distribution {
outputDirectory = File("$projectDir/web")
}
}
}
}abstract class KotlinWebpack : Task {
abstract val entry: RegularFileProperty
abstract val outputFileName: Property<String>
abstract val destinationDirectory: DirectoryProperty
abstract val sourceMaps: Property<Boolean>
abstract val devtool: Property<String>
abstract val mode: Property<String>
abstract val configDirectory: DirectoryProperty
abstract val reportEvaluatedConfigFile: RegularFileProperty
}Advanced WebPack Configuration:
kotlin {
js(IR) {
browser {
webpackTask {
outputFileName = "bundle.[contenthash].js"
sourceMaps = false
mode = "production"
// Custom webpack configuration
File(project.projectDir, "webpack.config.d/custom.js").writeText("""
config.optimization = {
splitChunks: {
chunks: 'all'
}
};
""".trimIndent())
}
}
}
}// @file:JsModule annotation for NPM modules
@file:JsModule("lodash")
external fun debounce(func: () -> Unit, wait: Int): () -> Unit
// @JsNonModule for global libraries
@JsNonModule
@JsName("jQuery")
external val `$`: dynamic// Generate TypeScript definitions
tasks.register("generateTypeScriptDefinitions") {
dependsOn("compileKotlinJs")
doLast {
val outputDir = file("$buildDir/js/packages/${project.name}/kotlin")
// Generate .d.ts files from Kotlin/JS output
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-gradle-plugin