or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compilation-tasks.mddependency-management.mddsl-extensions.mdindex.mdjavascript-webassembly.mdmultiplatform-targets.mdplugin-configuration.md

javascript-webassembly.mddocs/

0

# JavaScript and WebAssembly Support

1

2

This document covers specialized support for Kotlin/JS and Kotlin/WebAssembly compilation with browser, Node.js, and other runtime targets.

3

4

```kotlin

5

import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

6

```

7

8

## JavaScript Targets

9

10

### JS Target Configuration

11

12

```kotlin { .api }

13

interface KotlinJsTarget : KotlinTarget {

14

val irTarget: Boolean

15

16

fun browser(configure: KotlinJsBrowserDsl.() -> Unit = {})

17

fun nodejs(configure: KotlinJsNodeDsl.() -> Unit = {})

18

19

val testRuns: NamedDomainObjectContainer<KotlinTargetTestRun<*>>

20

val compilations: NamedDomainObjectContainer<KotlinJsCompilation>

21

}

22

```

23

24

**Basic JS Target Setup:**

25

26

```kotlin

27

kotlin {

28

js(IR) { // Use IR compiler (recommended)

29

browser {

30

webpackTask {

31

outputFileName = "app.js"

32

sourceMaps = true

33

}

34

35

distribution {

36

outputDirectory = File("$projectDir/web")

37

}

38

}

39

40

nodejs {

41

runTask {

42

args.add("--experimental-modules")

43

}

44

}

45

}

46

}

47

```

48

49

### Browser Configuration

50

51

```kotlin { .api }

52

interface KotlinJsBrowserDsl {

53

fun webpackTask(configure: KotlinWebpack.() -> Unit)

54

fun runTask(configure: KotlinWebpack.() -> Unit)

55

fun testTask(configure: KotlinWebpack.() -> Unit)

56

57

val distribution: Distribution

58

}

59

60

interface KotlinWebpack : Task {

61

var outputFileName: String

62

var sourceMaps: Boolean

63

var devServer: KotlinWebpackDevServer?

64

65

val entry: RegularFileProperty

66

val destinationDirectory: DirectoryProperty

67

val configDirectory: DirectoryProperty

68

}

69

70

interface KotlinWebpackDevServer {

71

var enabled: Boolean

72

var port: Int

73

var proxy: MutableMap<String, String>

74

var static: MutableList<String>

75

}

76

```

77

78

**Advanced Browser Configuration:**

79

80

```kotlin

81

kotlin {

82

js(IR) {

83

browser {

84

webpackTask {

85

outputFileName = "myapp.js"

86

sourceMaps = true

87

88

devServer = KotlinWebpackDevServer().apply {

89

enabled = true

90

port = 3000

91

proxy.apply {

92

put("/api", "http://localhost:8080")

93

}

94

static.apply {

95

add("static")

96

add("resources")

97

}

98

}

99

}

100

101

runTask {

102

sourceMaps = false

103

devtool = "eval-cheap-source-map"

104

}

105

106

testTask {

107

useKarma {

108

useChromeHeadless()

109

useFirefoxHeadless()

110

}

111

}

112

113

distribution {

114

outputDirectory = File("$buildDir/distributions")

115

}

116

}

117

}

118

}

119

```

120

121

### Node.js Configuration

122

123

```kotlin { .api }

124

interface KotlinJsNodeDsl {

125

fun runTask(configure: NodeJsExec.() -> Unit)

126

fun testTask(configure: NodeJsExec.() -> Unit)

127

}

128

129

interface NodeJsExec : Exec {

130

val args: MutableList<String>

131

val environment: MutableMap<String, String>

132

val ignoreExitValue: Boolean

133

}

134

```

135

136

**Node.js Configuration Example:**

137

138

```kotlin

139

kotlin {

140

js(IR) {

141

nodejs {

142

runTask {

143

args.addAll("--experimental-modules", "--trace-warnings")

144

environment["NODE_ENV"] = "development"

145

}

146

147

testTask {

148

args.add("--experimental-vm-modules")

149

environment["NODE_OPTIONS"] = "--max-old-space-size=4096"

150

}

151

}

152

}

153

}

154

```

155

156

## WebAssembly Targets

157

158

### WASM-JS Target

159

160

```kotlin { .api }

161

@ExperimentalWasmDsl

162

interface KotlinWasmJsTarget : KotlinTarget {

163

fun browser(configure: KotlinWasmJsBrowserDsl.() -> Unit = {})

164

fun nodejs(configure: KotlinWasmJsNodeDsl.() -> Unit = {})

165

fun d8(configure: KotlinWasmJsD8Dsl.() -> Unit = {})

166

}

167

168

interface KotlinWasmJsBrowserDsl {

169

fun webpackTask(configure: KotlinWebpack.() -> Unit)

170

fun runTask(configure: KotlinWebpack.() -> Unit)

171

fun testTask(configure: KotlinWebpack.() -> Unit)

172

}

173

```

174

175

**WASM-JS Configuration:**

176

177

```kotlin

178

kotlin {

179

@OptIn(ExperimentalWasmDsl::class)

180

wasmJs {

181

browser {

182

webpackTask {

183

outputFileName = "app.wasm.js"

184

sourceMaps = true

185

}

186

}

187

188

nodejs {

189

runTask {

190

args.add("--experimental-wasm-modules")

191

}

192

}

193

194

d8 {

195

// V8 shell configuration for testing

196

}

197

}

198

}

199

```

200

201

### WASM-WASI Target

202

203

```kotlin { .api }

204

@ExperimentalWasmDsl

205

interface KotlinWasmWasiTarget : KotlinTarget {

206

fun nodejs(configure: KotlinWasmWasiNodeDsl.() -> Unit = {})

207

}

208

```

209

210

**WASM-WASI Configuration:**

211

212

```kotlin

213

kotlin {

214

wasmWasi {

215

nodejs {

216

runTask {

217

args.addAll("--experimental-wasi-unstable-preview1", "--experimental-wasm-bigint")

218

}

219

}

220

}

221

}

222

```

223

224

## NPM and Yarn Integration

225

226

### NPM Dependencies

227

228

```kotlin { .api }

229

// NPM dependency declaration

230

fun npm(name: String, version: String): NpmDependency

231

fun npm(name: String, version: String, generateExternals: Boolean): NpmDependency

232

fun devNpm(name: String, version: String): NpmDependency

233

fun peerNpm(name: String, version: String): NpmDependency

234

fun optionalNpm(name: String, version: String): NpmDependency

235

```

236

237

**NPM Usage Example:**

238

239

```kotlin

240

kotlin {

241

js(IR) {

242

browser()

243

nodejs()

244

}

245

246

sourceSets {

247

jsMain {

248

dependencies {

249

// Kotlin wrappers

250

implementation("org.jetbrains.kotlin-wrappers:kotlin-react:18.2.0-pre.467")

251

implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:18.2.0-pre.467")

252

253

// NPM packages

254

implementation(npm("react", "18.2.0"))

255

implementation(npm("react-dom", "18.2.0"))

256

implementation(npm("lodash", "4.17.21"))

257

258

// Development dependencies

259

implementation(devNpm("webpack", "5.88.0"))

260

implementation(devNpm("webpack-dev-server", "4.15.1"))

261

}

262

}

263

}

264

}

265

```

266

267

### Yarn Configuration

268

269

```kotlin { .api }

270

// Configure Yarn in root project

271

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {

272

rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().apply {

273

yarnLockMismatchReport = org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport.WARNING

274

reportNewYarnLock = false

275

yarnLockAutoReplace = false

276

}

277

}

278

```

279

280

## D8 Engine Support

281

282

### D8 Configuration

283

284

```kotlin { .api }

285

interface D8RootExtension {

286

val version: Property<String>

287

val downloadBaseUrl: Property<String>

288

val installationDirectory: DirectoryProperty

289

}

290

291

interface D8EnvSpec {

292

val version: String

293

val downloadUrl: String

294

val executablePath: String

295

}

296

```

297

298

**D8 Setup:**

299

300

```kotlin

301

// Configure D8 for WASM testing

302

rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.wasm.d8.D8RootExtension> {

303

version.set("11.4.183")

304

downloadBaseUrl.set("https://storage.googleapis.com/chromium-v8/official/canary")

305

}

306

307

kotlin {

308

wasmJs {

309

d8 {

310

// D8-specific configuration

311

}

312

}

313

}

314

```

315

316

### D8 Tasks

317

318

```kotlin { .api }

319

abstract class D8Exec : AbstractExecTask<D8Exec> {

320

abstract val inputFileProperty: RegularFileProperty

321

abstract val outputFileProperty: RegularFileProperty

322

abstract val d8Args: ListProperty<String>

323

}

324

325

abstract class D8SetupTask : DefaultTask() {

326

abstract val d8EnvSpec: Property<D8EnvSpec>

327

abstract val destinationDirectory: DirectoryProperty

328

}

329

```

330

331

## JavaScript Module Systems

332

333

### Module Kind Configuration

334

335

```kotlin { .api }

336

enum class KotlinJsModuleKind {

337

MODULE_AMD, // AMD modules (require.js)

338

MODULE_COMMONJS, // CommonJS modules (Node.js)

339

MODULE_PLAIN, // Plain JS (global scope)

340

MODULE_UMD, // Universal Module Definition

341

MODULE_ES // ES6 modules

342

}

343

```

344

345

**Module Configuration:**

346

347

```kotlin

348

kotlin {

349

js(IR) {

350

compilations.all {

351

compilerOptions.configure {

352

moduleKind.set(KotlinJsModuleKind.MODULE_ES)

353

target.set("es2015")

354

sourceMap.set(true)

355

sourceMapEmbedSources.set(org.jetbrains.kotlin.gradle.dsl.SourceMapEmbedSources.SOURCE_MAP_SOURCE_CONTENT_ALWAYS)

356

}

357

}

358

}

359

}

360

```

361

362

## Testing Configuration

363

364

### Browser Testing

365

366

```kotlin { .api }

367

// Karma test configuration

368

testTask {

369

useKarma {

370

useChromeHeadless()

371

useFirefoxHeadless()

372

373

webpackConfig.cssSupport {

374

enabled.set(true)

375

}

376

377

webpackConfig.bundleAnalyzerReportDir = file("$buildDir/reports/webpack")

378

}

379

}

380

```

381

382

### Node.js Testing

383

384

```kotlin

385

kotlin {

386

js(IR) {

387

nodejs {

388

testTask {

389

args.addAll(

390

"--experimental-vm-modules",

391

"--experimental-wasm-modules"

392

)

393

394

environment["NODE_OPTIONS"] = "--max-old-space-size=4096"

395

environment["NODE_ENV"] = "test"

396

}

397

}

398

}

399

}

400

```

401

402

## Build Output Structure

403

404

### Distribution Directory

405

406

```kotlin { .api }

407

interface Distribution {

408

var outputDirectory: File

409

var name: String

410

411

fun from(source: Any)

412

fun exclude(pattern: String)

413

fun include(pattern: String)

414

}

415

```

416

417

**Distribution Configuration:**

418

419

```kotlin

420

kotlin {

421

js(IR) {

422

browser {

423

distribution {

424

outputDirectory = File("$projectDir/web")

425

}

426

}

427

}

428

}

429

```

430

431

## WebPack Integration

432

433

### WebPack Task Configuration

434

435

```kotlin { .api }

436

abstract class KotlinWebpack : Task {

437

abstract val entry: RegularFileProperty

438

abstract val outputFileName: Property<String>

439

abstract val destinationDirectory: DirectoryProperty

440

441

abstract val sourceMaps: Property<Boolean>

442

abstract val devtool: Property<String>

443

abstract val mode: Property<String>

444

445

abstract val configDirectory: DirectoryProperty

446

abstract val reportEvaluatedConfigFile: RegularFileProperty

447

}

448

```

449

450

**Advanced WebPack Configuration:**

451

452

```kotlin

453

kotlin {

454

js(IR) {

455

browser {

456

webpackTask {

457

outputFileName = "bundle.[contenthash].js"

458

sourceMaps = false

459

mode = "production"

460

461

// Custom webpack configuration

462

File(project.projectDir, "webpack.config.d/custom.js").writeText("""

463

config.optimization = {

464

splitChunks: {

465

chunks: 'all'

466

}

467

};

468

""".trimIndent())

469

}

470

}

471

}

472

}

473

```

474

475

## External Declarations

476

477

### JavaScript Externals

478

479

```kotlin

480

// @file:JsModule annotation for NPM modules

481

@file:JsModule("lodash")

482

external fun debounce(func: () -> Unit, wait: Int): () -> Unit

483

484

// @JsNonModule for global libraries

485

@JsNonModule

486

@JsName("jQuery")

487

external val `$`: dynamic

488

```

489

490

### TypeScript Definitions

491

492

```kotlin

493

// Generate TypeScript definitions

494

tasks.register("generateTypeScriptDefinitions") {

495

dependsOn("compileKotlinJs")

496

497

doLast {

498

val outputDir = file("$buildDir/js/packages/${project.name}/kotlin")

499

// Generate .d.ts files from Kotlin/JS output

500

}

501

}

502

```