Use Kotlin code from JavaScript
Depending on the selected JavaScript Module system, the Kotlin/JS compiler generates different output. But in general, the Kotlin compiler generates normal JavaScript classes, functions and properties, which you can freely use from JavaScript code. There are some subtle things you should remember, though.
Isolating declarations in a separate JavaScript object in plain mode
If you have explicitly set your module kind to be plain, Kotlin creates an object that contains all Kotlin declarations from the current module. This is done to prevent spoiling the global object. This means that for a module myModule, all declarations are available to JavaScript via the myModule object. For example:
This function can be called from JavaScript like this:
Calling the function directly like this is not applicable when you compile your Kotlin module to JavaScript modules like UMD (the default setting for both browser and nodejs targets), ESM, CommonJS, or AMD. In these cases, your declarations are exposed according to the chosen JavaScript module system. For example, when using UMD, ESM, or CommonJS, your call site would look like this:
For more information about JavaScript module systems, see JavaScript Modules.
Package structure
For most of the module systems (CommonJS, Plain, and UMD), Kotlin exposes its package structure to JavaScript. Unless you define your declarations in the root package, you have to use fully qualified names in JavaScript. For example:
For example, when using UMD or CommonJS, your call site could look like this:
When using plain as a module system setting, the call site would be:
When targeting ECMAScript Modules (ESM), package information is not preserved to improve the application bundle size and match the typical layout of ESM packages. In this case, the consumption of the Kotlin declarations with ES modules looks like this:
@JsName annotation
In some cases (for example, to support overloads), the Kotlin compiler mangles the names of generated functions and attributes in JavaScript code. To control the generated names, you can use the @JsName annotation:
Now you can use this class from JavaScript in the following way:
If we didn't specify the @JsName annotation, the name of the corresponding function would contain a suffix calculated from the function signature, for example hello_61zpoe$.
Note that there are some cases in which the Kotlin compiler does not apply mangling:
externaldeclarations are not mangled.Any overridden functions in non-
externalclasses inheriting fromexternalclasses are not mangled.
The parameter of @JsName is required to be a constant string literal which is a valid identifier. The compiler will report an error on any attempt to pass non-identifier string to @JsName. The following example produces a compile-time error:
@JsExport annotation
By applying the @JsExport annotation to a top-level declaration (like a class or function), you make the Kotlin declaration available from JavaScript. The annotation exports all nested declarations with the name given in Kotlin. It can also be applied on file-level using @file:JsExport.
To resolve ambiguities in exports (like overloads for functions with the same name), you can use the @JsExport annotation together with @JsName to specify the names for the generated and exported functions.
Currently, the @JsExport annotation is the only way to make your functions visible from Kotlin.
For multiplatform projects, @JsExport is available in common code as well. It only has an effect when compiling for the JavaScript target, and allows you to also export Kotlin declarations that are not platform specific.
@JsStatic
The @JsStatic annotation instructs the compiler to generate additional static methods for the target declaration. This helps you use static members from your Kotlin code directly in JavaScript.
You can apply the @JsStatic annotation to functions defined in named objects, as well as in companion objects declared inside classes and interfaces. If you use this annotation, the compiler will generate both a static method of the object and an instance method in the object itself. For example:
Now, the callStatic() function is static in JavaScript while the callNonStatic() function is not:
It's also possible to apply the @JsStatic annotation to a property of an object or a companion object, making its getter and setter methods static members in that object or the class containing the companion object.
Use BigInt type to represent Kotlin's Long type
Kotlin/JS uses JavaScript's built-in BigInt type to represent Kotlin Long values when compiling to modern JavaScript (ES2020).
To enable support for the BigInt type, you need to add the following compiler option to your build.gradle(.kts) file:
This feature is Experimental. Share your feedback in our issue tracker, YouTrack.
Use Long in exported declarations
Since Kotlin's Long type can compile to JavaScript's BigInt type, Kotlin/JS supports exporting Long values to JavaScript.
To enable this feature:
Allow exporting
Longin Kotlin/JS. Add the following compiler option to thefreeCompilerArgsattribute in yourbuild.gradle(.kts)file:
Enable the
BigInttype. See how to enable it in Use ofBigInttype to represent Kotlin'sLongtype.
Kotlin types in JavaScript
See how Kotlin types are mapped to JavaScript ones:
Kotlin | JavaScript | Comments |
|---|---|---|
|
| |
|
| The number represents the character's code. |
|
| Needs the |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| Carries the property |
|
| |
|
| |
|
| Carries the property |
|
| Carries the property |
|
| Exposes an |
|
| Exposes an ES2015 |
|
| Exposes an ES2015 |
| Undefined | Exportable when used as return type, but not when used as parameter type. |
|
| |
|
| |
|
| Enum entries are exposed as static class properties ( |
Nullable |
| |
All other Kotlin types, except for those marked with | Not supported | Includes Kotlin's unsigned integer types. |
Additionally, it is important to know that:
Kotlin preserves overflow semantics for
kotlin.Int,kotlin.Byte,kotlin.Short,kotlin.Charandkotlin.Long.Kotlin cannot distinguish between numeric types at runtime (except for
kotlin.Long), so the following code works:fun f() { val x: Int = 23 val y: Any = x println(y as Float) }Kotlin preserves lazy object initialization in JavaScript.