I thought I had understood the concepts of Kotlin multiplatform and the hierarchy of source sets:
- Code that can be run on every platform goes into
commonMain
, code that can only be run in the JVM goes intojvmMain
, code that can only be run on a JavaScript engine goes intojsMain
. - Also, declarations for which there are platform-specific implementations goes into
commonMain
, while the implementations go intojvmMain
andjsMain
. - A large part of the Kotlin standard library can be used from
commonMain
because there are implementations for JVM and JS.
But now that I am trying to make my multiplatform library accessible from JavaScript/TypeScript, I’m confused. Why is it that for a multiplatform library to be usable from JS code…
- every declaration must be annotated with
@JsExport
(assuming the IR backend)? Of course if it’s public I want to export it - otherwise I would have put it injvmMain
etc., notcommonMain
! - even simple types like
kotlin.collections.List
are not supported? There must be a JS implementation in the standard library, so why can it not be used? My library should get a dependency on the Kotlin JS standard library (or have the used parts baked in by Webpack), then the consuming JavaScript code has access to it as well, right?
These restrictions seem to undermine the elegant multiplatform model. Can someone please explain and also give a perspective on the future of these issues?
Update:
Now I’m even more baffled, because this works in a regular TypeScript project:
# Install the official Kotlin standard library
npm install -save kotlin@1.6.10
# Install TypeScript definitions provided by a third party,
# because for some unknown reason, the standard library
# doesn't provide them
npm install -save @mtm-solutions/kotlin-stdlib-wrapper@1.1.3
import * as kotlinStdlibWrapper from "@mtm-solutions/kotlin-stdlib-wrapper"
type List<T> = kotlinStdlibWrapper.kotlin.collections.List<T>
const listOf = kotlinStdlibWrapper.kotlin.collections.listOf
const list: List<string> = listOf(["a", "b"])
console.log(list.get(1)) // "b"
So it is obviously possible to use the List
type from the standard library from a JavaScript/TypeScript project, yet Kotlin multiplatform disallows exporting declarations that use it.