Interoperability with JavaScript
Kotlin/Wasm allows you to both use JavaScript code from Kotlin and Kotlin code from JavaScript.
The Kotlin/JS compiler already provides the ability to transpile your Kotlin code to JavaScript. The Kotlin/Wasm interoperability with JavaScript is designed in a similar way, taking into account that JavaScript is a dynamically typed language compared to Kotlin. Follow our guide to configure interoperability in your projects.
Remember that Kotlin/Wasm is still Experimental, and some features are not supported yet. We're planning to improve interoperability with JavaScript by implementing some of the missing features or similar functionality.
Use JavaScript code from Kotlin
external modifier
To access JavaScript declarations defined in the global scope, mark them with the external
modifier. Consider this JavaScript code sample:
Here's how you can use this JavaScript code in Kotlin:
See the full code in the example project Kotlin/Wasm browser.
@JsFun annotation
To include a small piece of JS code in your Kotlin/Wasm module, use the @JsFun
annotation with external top-level functions. The annotation argument should be a string with JS code that evaluates a function with a matching signature:
To make it shorter, use arrow syntax:
The Kotlin compiler doesn't verify these JavaScript snippets and evaluates them as-is. Syntax errors, if any, will be reported when running your JavaScript.
@JsModule
To indicate that an external
class, package, function, or property is a JavaScript module, use the @JsModule
annotation. Consider this JavaScript code sample:
Here's how you can use this JavaScript code in Kotlin:
Use Kotlin code from JavaScript
@JsExport annotation
To make the Kotlin/Wasm declaration available from JavaScript, use the @JsExport
annotation with external top-level functions:
Now you can use this function from JavaScript in the following way:
Functions marked at @JsExport
are visible as properties on a default
export of the generated .mjs
module. Kotlin types in JavaScript In Kotlin/JS, values are implemented internally as JavaScript primitives and objects. They are passed to and from JavaScript without wrapping or copying.
However, in Kotlin/Wasm, objects have a different representation and are not interchangeable with JavaScript. When you pass a Kotlin object to JavaScript, it's considered as an empty opaque object by default.
The only thing you can do is store it and pass Kotlin objects back to Wasm. However, for primitive types, Kotlin/Wasm can adapt these values so that they can be useful in JavaScript by either copying or wrapping. For efficiency purposes, this is done statically. It's important that these special concrete types are present in function signatures. For example:
Kotlin types in JavaScript
Supported types
See how Kotlin types are mapped to JavaScript ones:
Kotlin | JavaScript | Comments |
---|---|---|
|
| |
|
| |
|
| |
|
| |
|
| String content is copied. In the future, the stringref proposal could allow the zero-copy string interop. |
| Undefined | Only when non-nullable and in functions returning position. |
Function type, for example ( | Function reference | Parameters and return values of function types follow the same type of conversion rules. |
| Any JS value with given properties | |
| Corresponding JS class | |
Other Kotlin types | Not supported | This includes type |
Nullable | Type / | |
Type parameters | Same as the upper bound | In interop declarations, only external types, like |
Exception handling
The Kotlin/Wasm try-catch
expression can't catch the JavaScript exceptions.
If you try to use JavaScript try-catch
expression to catch the Kotlin/Wasm exceptions, it'll look like a generic WebAssembly.Exception
without directly accessible messages and data.
Workarounds for Kotlin/JS features non-supported in Kotlin/Wasm
Dynamic type
Kotlin/JS dynamic type used for interoperability with untyped or loosely typed objects is not supported yet. In many cases, you can use external interfaces and the @JsFun
annotation instead:
Inline JavaScript
The js()
function used to inline JavaScript code to Kotlin code is not supported yet. Use the @JsFun
annotation instead:
Extending external interfaces and classes with non-external classes
Extending JavaScript classes and using external interfaces is not supported yet. Use the @JsFun
annotation instead: