[K/JS, K/Wasm] Commonize WasmJs interop for the new `webMain` source-set

^KT-79394 Fixed


Co-authored-by: Filipp Zhinkin <filipp.zhinkin@jetbrains.com>
Co-authored-by: Sergej Jaskiewicz <Sergej.Jaskiewicz@jetbrains.com>

Merge-request: KT-MR-22642
Merged-by: Artem Kobzar <Artem.Kobzar@jetbrains.com>
diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt
index a600d42..2c18216 100644
--- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt
+++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt
@@ -78,7 +78,8 @@
             partialLinkageSupport = createPartialLinkageSupportForLinker(
                 partialLinkageConfig = configuration.partialLinkageConfig,
                 builtIns = psi2IrContext.irBuiltIns,
-                messageCollector = messageCollector
+                messageCollector = messageCollector,
+                platform = psi2IrContext.moduleDescriptor.platform!!
             ),
             ICData(icData.map { it.irData!! }, containsErrorCode = false),
             stubGenerator = stubGenerator
diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt
index 3793304..d4a27c9 100644
--- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt
+++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt
@@ -167,7 +167,8 @@
             partialLinkageSupport = createPartialLinkageSupportForLinker(
                 partialLinkageConfig = compilerConfiguration.partialLinkageConfig,
                 builtIns = irBuiltIns,
-                messageCollector = messageCollector
+                messageCollector = messageCollector,
+                platform = moduleDescriptor.platform!!
             ),
             friendModules = mapOf(mainLibrary.uniqueName to mainModuleFriends.map { it.uniqueName })
         )
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/ClassifierExplorer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/ClassifierExplorer.kt
index a3e06ec..4b44b9b 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/ClassifierExplorer.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/ClassifierExplorer.kt
@@ -24,12 +24,15 @@
 import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.ir.visitors.IrTypeVisitorVoid
 import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
+import org.jetbrains.kotlin.platform.TargetPlatform
+import org.jetbrains.kotlin.platform.isJs
 import org.jetbrains.kotlin.utils.addIfNotNull
 import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSources.Module as PLModule
 
 internal class ClassifierExplorer(
     private val builtIns: IrBuiltIns,
     private val stubGenerator: MissingDeclarationStubGenerator,
+    private val platform: TargetPlatform
 ) {
     private val permittedAnnotationArrayParameterSymbols: Set<IrClassSymbol> by lazy {
         setOf(
@@ -227,7 +230,9 @@
                 return InvalidInheritance(symbol, illegalSuperClassSymbols)
         } else {
             // Check the number of non-interface supertypes.
-            val superClassSymbols = superTypeSymbols.filter { !it.owner.isInterface }
+            // We allow to have Any class together with another class in the list to support cross-compilation of the webMain
+            // to both JS and WasmJS, since the `JsAny` WasmJs external interface is actualized as `Any` on the JS side (and JS is a class)
+            val superClassSymbols = superTypeSymbols.filter { !it.owner.isInterface && (it != builtIns.anyClass || platform.isJs()) }
             val superClassSymbol = when (superClassSymbols.size) {
                 0 -> return null // It can be only Any.
                 1 -> superClassSymbols.first()
diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt
index 39ca2eb..9679cd6 100644
--- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt
+++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt
@@ -16,22 +16,29 @@
 import org.jetbrains.kotlin.ir.symbols.IrSymbol
 import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
 import org.jetbrains.kotlin.ir.util.SymbolTable
+import org.jetbrains.kotlin.platform.TargetPlatform
 
 fun createPartialLinkageSupportForLinker(
     partialLinkageConfig: PartialLinkageConfig,
     builtIns: IrBuiltIns,
-    messageCollector: MessageCollector
+    messageCollector: MessageCollector,
+    platform: TargetPlatform,
 ): PartialLinkageSupportForLinker = if (partialLinkageConfig.isEnabled)
-    PartialLinkageSupportForLinkerImpl(builtIns, PartialLinkageLogger(messageCollector, partialLinkageConfig.logLevel))
+    PartialLinkageSupportForLinkerImpl(
+        builtIns = builtIns,
+        platform = platform,
+        logger = PartialLinkageLogger(messageCollector, partialLinkageConfig.logLevel),
+    )
 else
     PartialLinkageSupportForLinker.DISABLED
 
 internal class PartialLinkageSupportForLinkerImpl(
     builtIns: IrBuiltIns,
-    private val logger: PartialLinkageLogger
+    private val logger: PartialLinkageLogger,
+    platform: TargetPlatform
 ) : PartialLinkageSupportForLinker {
     private val stubGenerator = MissingDeclarationStubGenerator(builtIns)
-    private val classifierExplorer = ClassifierExplorer(builtIns, stubGenerator)
+    private val classifierExplorer = ClassifierExplorer(builtIns, stubGenerator, platform)
     private val patcher = PartiallyLinkedIrTreePatcher(builtIns, classifierExplorer, stubGenerator, logger)
 
     /**
diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt
index 7002202..f08fbde 100644
--- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt
+++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt
@@ -231,7 +231,8 @@
         partialLinkageSupport = createPartialLinkageSupportForLinker(
             partialLinkageConfig = configuration.partialLinkageConfig,
             builtIns = irBuiltIns,
-            messageCollector = messageCollector
+            messageCollector = messageCollector,
+            platform = moduleDescriptor.platform!!,
         ),
         icData = null,
         friendModules = friendModules
@@ -289,7 +290,8 @@
         partialLinkageSupport = createPartialLinkageSupportForLinker(
             partialLinkageConfig = configuration.partialLinkageConfig,
             builtIns = irBuiltIns,
-            messageCollector = messageCollector
+            messageCollector = messageCollector,
+            platform = psi2IrContext.moduleDescriptor.platform!!
         ),
         icData = null,
         friendModules = friendModules,
diff --git a/compiler/testData/codegen/box/size/add.kt b/compiler/testData/codegen/box/size/add.kt
index 0a40799..63cf5d1 100644
--- a/compiler/testData/codegen/box/size/add.kt
+++ b/compiler/testData/codegen/box/size/add.kt
@@ -1,8 +1,8 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  54_727
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_955
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  54_055
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_865
 // WASM_OPT_EXPECTED_OUTPUT_SIZE:           76
 
 // FILE: test.kt
diff --git a/compiler/testData/codegen/box/size/helloWorld.kt b/compiler/testData/codegen/box/size/helloWorld.kt
index e286cf8..035c09a 100644
--- a/compiler/testData/codegen/box/size/helloWorld.kt
+++ b/compiler/testData/codegen/box/size/helloWorld.kt
@@ -1,9 +1,9 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  55_043
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_890
-// WASM_OPT_EXPECTED_OUTPUT_SIZE:        6_381
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  54_371
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_831
+// WASM_OPT_EXPECTED_OUTPUT_SIZE:        6_270
 
 fun box(): String {
     println("Hello, World!")
diff --git a/compiler/testData/codegen/box/size/helloWorldPromise.kt b/compiler/testData/codegen/box/size/helloWorldPromise.kt
index b132f8b..b049932 100644
--- a/compiler/testData/codegen/box/size/helloWorldPromise.kt
+++ b/compiler/testData/codegen/box/size/helloWorldPromise.kt
@@ -1,9 +1,9 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 55_142
-// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  6_126
-// WASM_OPT_EXPECTED_OUTPUT_SIZE:       6_576
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 54_474
+// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  6_067
+// WASM_OPT_EXPECTED_OUTPUT_SIZE:       6_465
 
 // FILE: test.kt
 
diff --git a/compiler/testData/codegen/box/size/objectsOptimization.kt b/compiler/testData/codegen/box/size/objectsOptimization.kt
index c8906e7..3c5650d 100644
--- a/compiler/testData/codegen/box/size/objectsOptimization.kt
+++ b/compiler/testData/codegen/box/size/objectsOptimization.kt
@@ -1,9 +1,9 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 59_637
-// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  5_821
-// WASM_OPT_EXPECTED_OUTPUT_SIZE:       7_798
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 58_966
+// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  5_762
+// WASM_OPT_EXPECTED_OUTPUT_SIZE:       7_654
 
 object Simple
 
diff --git a/compiler/testData/codegen/box/size/ok.kt b/compiler/testData/codegen/box/size/ok.kt
index 56f28aa..b2c2373 100644
--- a/compiler/testData/codegen/box/size/ok.kt
+++ b/compiler/testData/codegen/box/size/ok.kt
@@ -1,8 +1,8 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 54_776
-// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  5_821
-// WASM_OPT_EXPECTED_OUTPUT_SIZE:       6_285
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 54_104
+// WASM_DCE_EXPECTED_OUTPUT_SIZE:  mjs  5_762
+// WASM_OPT_EXPECTED_OUTPUT_SIZE:       6_174
 
 fun box() = "OK"
\ No newline at end of file
diff --git a/compiler/testData/codegen/box/size/removeUnusedOverride.kt b/compiler/testData/codegen/box/size/removeUnusedOverride.kt
index 805512e..513fbb6 100644
--- a/compiler/testData/codegen/box/size/removeUnusedOverride.kt
+++ b/compiler/testData/codegen/box/size/removeUnusedOverride.kt
@@ -2,9 +2,9 @@
 // TARGET_BACKEND: WASM
 
 // RUN_THIRD_PARTY_OPTIMIZER
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  55_464
-// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_821
-// WASM_OPT_EXPECTED_OUTPUT_SIZE:        6_289
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm  54_786
+// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs    5_762
+// WASM_OPT_EXPECTED_OUTPUT_SIZE:        6_178
 
 interface I {
     fun foo() = "OK"
diff --git a/core/compiler.common.js/src/org/jetbrains/kotlin/name/JsStandardClassIds.kt b/core/compiler.common.js/src/org/jetbrains/kotlin/name/JsStandardClassIds.kt
index 8edc47f..9acebc5 100644
--- a/core/compiler.common.js/src/org/jetbrains/kotlin/name/JsStandardClassIds.kt
+++ b/core/compiler.common.js/src/org/jetbrains/kotlin/name/JsStandardClassIds.kt
@@ -74,7 +74,7 @@
         val JsExportIgnore = JsExport.createNestedClassId(Name.identifier("Ignore"))
 
         @JvmField
-        val JsFun = "JsFun".jsId()
+        val JsFun = "JsFun".id()
 
         @JvmField
         val JsOutlinedFunction = "JsOutlinedFunction".jsId()
@@ -105,5 +105,6 @@
 }
 
 private fun String.jsId() = ClassId(JsStandardClassIds.BASE_JS_PACKAGE, Name.identifier(this))
+private fun String.id() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this))
 
 private fun String.callableId(packageName: FqName) = CallableId(packageName, Name.identifier(this))
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/linkKlibs.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/linkKlibs.kt
index 76c9126..95ba9fd 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/linkKlibs.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/linkKlibs.kt
@@ -158,7 +158,8 @@
                 partialLinkageSupport = createPartialLinkageSupportForLinker(
                         partialLinkageConfig = partialLinkageConfig,
                         builtIns = generatorContext.irBuiltIns,
-                        messageCollector = messageCollector
+                        messageCollector = messageCollector,
+                        platform = moduleDescriptor.platform!!
                 ),
                 libraryBeingCached = config.libraryToCache,
                 userVisibleIrModulesSupport = config.userVisibleIrModulesSupport,
diff --git a/libraries/stdlib/build.gradle.kts b/libraries/stdlib/build.gradle.kts
index a0792f8..fb2b64a 100644
--- a/libraries/stdlib/build.gradle.kts
+++ b/libraries/stdlib/build.gradle.kts
@@ -411,7 +411,15 @@
             kotlin.srcDir("common-non-jvm/src")
         }
 
+        val webMain by creating {
+            dependsOn(commonMain.get())
+            kotlin {
+                srcDir("jsAndWasmJsCommon/src")
+            }
+        }
+
         val jsMain by getting {
+            dependsOn(webMain)
             dependsOn(commonNonJvmMain)
             val prepareJsIrMainSources by tasks.registering(Sync::class)
             kotlin {
@@ -511,6 +519,7 @@
         }
 
         val wasmJsMain by getting {
+            dependsOn(webMain)
             dependsOn(wasmCommonMain)
             kotlin {
                 srcDir("wasm/js/builtins")
diff --git a/libraries/stdlib/js-ir-minimal-for-test/build.gradle.kts b/libraries/stdlib/js-ir-minimal-for-test/build.gradle.kts
index bf8d0c03..083bd03e 100644
--- a/libraries/stdlib/js-ir-minimal-for-test/build.gradle.kts
+++ b/libraries/stdlib/js-ir-minimal-for-test/build.gradle.kts
@@ -108,6 +108,19 @@
     into(layout.buildDirectory.dir("commonNonJvmMainSources"))
 }
 
+val jsAndWasmJsCommonSources by task<Sync> {
+    val jsAndWasmJsDir = file("$rootDir/libraries/stdlib/jsAndWasmJsCommon")
+
+    from("$jsAndWasmJsDir/src") {
+        include(
+            "kotlin/js/annotations.kt",
+            "kotlin/js/core.kt",
+        )
+    }
+
+    into(layout.buildDirectory.dir("jsAndWasmJsCommon"))
+}
+
 val jsMainSources by task<Sync> {
     dependsOn(":kotlin-stdlib:prepareJsIrMainSources")
     val jsDir = file("$rootDir/libraries/stdlib/js")
@@ -127,8 +140,9 @@
             "kotlin/GroupingJs.kt",
             "kotlin/ItemArrayLike.kt",
             "kotlin/io/**",
+            "kotlin/wasmJs/**",
             "kotlin/json.kt",
-            "kotlin/promise.kt",
+            "kotlin/Promise.kt",
             "kotlin/regexp.kt",
             "kotlin/sequenceJs.kt",
             "kotlin/throwableExtensions.kt",
@@ -172,7 +186,12 @@
             dependsOn(commonMain)
             kotlin.srcDir(files(commonNonJvmMainSources.map { it.destinationDir }))
         }
+        val jsAndWasmJsCommon by creating {
+            dependsOn(commonMain)
+            kotlin.srcDir(files(jsAndWasmJsCommonSources.map { it.destinationDir }))
+        }
         named("jsMain") {
+            dependsOn(jsAndWasmJsCommon)
             dependsOn(commonNonJvmMain)
             kotlin.srcDir(files(jsMainSources.map { it.destinationDir }))
             kotlin.srcDir("js-src")
diff --git a/libraries/stdlib/js/runtime/kotlinJsHacks.kt b/libraries/stdlib/js/runtime/kotlinJsHacks.kt
index 187950f..3090479 100644
--- a/libraries/stdlib/js/runtime/kotlinJsHacks.kt
+++ b/libraries/stdlib/js/runtime/kotlinJsHacks.kt
@@ -30,22 +30,6 @@
 }
 
 /**
- * Implements the annotated function in JavaScript.
- * [code] must contain a JS expression that evaluates to JS function with signature that matches the annotated Kotlin function.
- *
- * For example, a function that adds two Doubles:
- *
- * ```kotlin
- * @JsFun("function (x, y) { return x + y; }")
- * external fun jsAdd(x: Double, y: Double): Double
- * ```
- *
- * @property code The JavaScript code
- */
-@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
-internal annotation class JsFun(val code: String)
-
-/**
  * The same as [JsFun], but is intended only for use by the compiler (to be precise, by `JsCodeOutliningLowering`).
  *
  * Unlike [JsFun], this annotation contains the debug information in the Source Map 3 format which maps offsets in [jsFunctionExpression]
diff --git a/libraries/stdlib/js/src/kotlin/Promise.kt b/libraries/stdlib/js/src/kotlin/Promise.kt
new file mode 100644
index 0000000..d304044
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/Promise.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+import kotlin.internal.LowPriorityInOverloadResolution
+
+/**
+ * Exposes the JavaScript [Promise object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) to Kotlin.
+ */
+@Suppress("NOT_DOCUMENTED")
+public actual open external class Promise<out T>
+actual constructor(executor: (resolve: (T) -> Unit, reject: (Throwable) -> Unit) -> Unit) {
+
+    @LowPriorityInOverloadResolution
+    public actual open fun <S> then(onFulfilled: ((T) -> S)?): Promise<S>
+
+    @LowPriorityInOverloadResolution
+    public actual open fun <S> then(onFulfilled: ((T) -> S)?, onRejected: ((Throwable) -> S)?): Promise<S>
+
+    public actual open fun <S> catch(onRejected: (Throwable) -> S): Promise<S>
+
+    public actual open fun finally(onFinally: () -> Unit): Promise<T>
+
+    public actual companion object {
+        public actual fun <S> all(promise: Array<out Promise<S>>): Promise<Array<out S>>
+
+        public actual fun <S> race(promise: Array<out Promise<S>>): Promise<S>
+
+        public actual fun reject(e: Throwable): Promise<Nothing>
+
+        public actual fun <S> resolve(e: S): Promise<S>
+        public actual fun <S> resolve(e: Promise<S>): Promise<S>
+    }
+}
+
+// It's workaround for KT-19672 since we can fix it properly until KT-11265 isn't fixed.
+@Suppress("NOTHING_TO_INLINE")
+public inline fun <T, S> Promise<Promise<T>>.then(
+    noinline onFulfilled: ((T) -> S)?
+): Promise<S> {
+    return this.unsafeCast<Promise<T>>().then(onFulfilled)
+}
+
+@Suppress("NOTHING_TO_INLINE")
+public inline fun <T, S> Promise<Promise<T>>.then(
+    noinline onFulfilled: ((T) -> S)?,
+    noinline onRejected: ((Throwable) -> S)?
+): Promise<S> {
+    return this.unsafeCast<Promise<T>>().then(onFulfilled, onRejected)
+}
diff --git a/libraries/stdlib/js/src/kotlin/annotationsJs.kt b/libraries/stdlib/js/src/kotlin/annotationsJs.kt
index f745b1f..b1d7d60 100644
--- a/libraries/stdlib/js/src/kotlin/annotationsJs.kt
+++ b/libraries/stdlib/js/src/kotlin/annotationsJs.kt
@@ -80,7 +80,7 @@
  * The annotation can be used on top-level external declarations (classes, properties, functions) and files.
  * In case of file (which can't be `external`) the following rule applies: all the declarations in
  * the file must be `external`. By applying `@JsModule(...)` on a file you tell the compiler to import a JavaScript object
- * that contain all the declarations from the file.
+ * that contains all the declarations from the file.
  *
  * Example:
  *
@@ -101,7 +101,7 @@
  */
 @Retention(AnnotationRetention.BINARY)
 @Target(CLASS, PROPERTY, FUNCTION, FILE)
-public annotation class JsModule(val import: String)
+public actual annotation class JsModule(actual val import: String)
 
 /**
  * Denotes an `external` declaration that can be used without module system.
@@ -137,7 +137,7 @@
 /**
  * Adds prefix to `external` declarations in a source file.
  *
- * JavaScript does not have concept of packages (namespaces). They are usually emulated by nested objects.
+ * JavaScript does not have a concept of packages (namespaces). They are usually emulated by nested objects.
  * The compiler turns references to `external` declarations either to plain unprefixed names (in case of *plain* modules)
  * or to plain imports.
  * However, if a JavaScript library provides its declarations in packages, you won't be satisfied with this.
@@ -165,7 +165,7 @@
  */
 @Retention(AnnotationRetention.BINARY)
 @Target(AnnotationTarget.FILE)
-public annotation class JsQualifier(val value: String)
+public actual annotation class JsQualifier(actual val value: String)
 
 /**
  * Exports top-level declaration on JS platform.
diff --git a/libraries/stdlib/js/src/kotlin/core.kt b/libraries/stdlib/js/src/kotlin/core.kt
index b8ea559..a7a8c70 100644
--- a/libraries/stdlib/js/src/kotlin/core.kt
+++ b/libraries/stdlib/js/src/kotlin/core.kt
@@ -31,7 +31,7 @@
  * external val prop: Float = definedExternally
  * ```
  */
-public external val definedExternally: Nothing
+public actual external val definedExternally: Nothing
 
 /**
  * Puts the given piece of a JavaScript code right into the calling function.
@@ -50,7 +50,8 @@
  *        You can safely refer to local variables of calling function (but not to local variables of outer functions),
  *        including parameters. You can't refer to functions, properties and classes by their short names.
  */
-public external fun js(code: String): dynamic
+@Suppress("EXPECT_ACTUAL_INCOMPATIBLE_RETURN_TYPE")
+public actual external fun js(code: String): dynamic
 
 
 /**
diff --git a/libraries/stdlib/js/src/kotlin/promise.kt b/libraries/stdlib/js/src/kotlin/promise.kt
deleted file mode 100644
index c34955e..0000000
--- a/libraries/stdlib/js/src/kotlin/promise.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
- * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
- */
-
-package kotlin.js
-
-import kotlin.internal.LowPriorityInOverloadResolution
-
-/**
- * Exposes the JavaScript [Promise object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) to Kotlin.
- */
-@Suppress("NOT_DOCUMENTED")
-public open external class Promise<out T>(executor: (resolve: (T) -> Unit, reject: (Throwable) -> Unit) -> Unit) {
-    @LowPriorityInOverloadResolution
-    public open fun <S> then(onFulfilled: ((T) -> S)?): Promise<S>
-
-    @LowPriorityInOverloadResolution
-    public open fun <S> then(onFulfilled: ((T) -> S)?, onRejected: ((Throwable) -> S)?): Promise<S>
-
-    public open fun <S> catch(onRejected: (Throwable) -> S): Promise<S>
-
-    public open fun finally(onFinally: () -> Unit): Promise<T>
-
-    public companion object {
-        public fun <S> all(promise: Array<out Promise<S>>): Promise<Array<out S>>
-
-        public fun <S> race(promise: Array<out Promise<S>>): Promise<S>
-
-        public fun reject(e: Throwable): Promise<Nothing>
-
-        public fun <S> resolve(e: S): Promise<S>
-        public fun <S> resolve(e: Promise<S>): Promise<S>
-    }
-}
-
-// It's workaround for KT-19672 since we can fix it properly until KT-11265 isn't fixed.
-@Suppress("NOTHING_TO_INLINE")
-public inline fun <T, S> Promise<Promise<T>>.then(
-    noinline onFulfilled: ((T) -> S)?
-): Promise<S> {
-    return this.unsafeCast<Promise<T>>().then(onFulfilled)
-}
-
-@Suppress("NOTHING_TO_INLINE")
-public inline fun <T, S> Promise<Promise<T>>.then(
-    noinline onFulfilled: ((T) -> S)?,
-    noinline onRejected: ((Throwable) -> S)?
-): Promise<S> {
-    return this.unsafeCast<Promise<T>>().then(onFulfilled, onRejected)
-}
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsAny.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsAny.kt
new file mode 100644
index 0000000..7d77717
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsAny.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+package kotlin.js
+
+import kotlin.internal.LowPriorityInOverloadResolution
+
+/**
+ * Any JavaScript value except null or undefined
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public actual typealias JsAny = Any
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@LowPriorityInOverloadResolution
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : JsAny> JsAny.unsafeCast(): T =
+    asDynamic().unsafeCast<T>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsArray.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsArray.kt
new file mode 100644
index 0000000..bd9b2b2
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsArray.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+import kotlin.internal.InlineOnly
+import kotlin.internal.LowPriorityInOverloadResolution
+
+/** JavaScript Array */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsArray<T> = Array<T>
+
+@InlineOnly
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun <T : JsAny?> JsArray(): JsArray<T> =
+    Array<JsAny?>(0) { null!! }.unsafeCast<JsArray<T>>()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual val JsArray<*>.length: Int
+    inline get() = unsafeCast<Array<*>>().size
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline operator fun <T : JsAny?> JsArray<T>.get(index: Int): T? = asDynamic()[index]
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline operator fun <T : JsAny?> JsArray<T>.set(index: Int, value: T) {
+    asDynamic()[index] = value
+}
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : JsAny?> JsArray<T>.toArray(): Array<T> = unsafeCast<Array<T>>()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : JsAny?> Array<T>.toJsArray(): JsArray<T> = unsafeCast<JsArray<T>>()
+
+/** Returns a new [List] containing all the elements of this [JsArray]. */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@LowPriorityInOverloadResolution
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : JsAny?> JsArray<T>.toList(): List<T> =
+    unsafeCast<Array<T>>().asList()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : JsAny?> List<T>.toJsArray(): JsArray<T> =
+    toTypedArray().toJsArray()
\ No newline at end of file
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsBigInt.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsBigInt.kt
new file mode 100644
index 0000000..c2fb0e5
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsBigInt.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsBigInt = Long
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual fun JsBigInt.toLong(): Long =
+    unsafeCast<Long>()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual fun Long.toJsBigInt(): JsBigInt =
+    unsafeCast<JsBigInt>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsBoolean.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsBoolean.kt
new file mode 100644
index 0000000..3806d1b
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsBoolean.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive boolean */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsBoolean = Boolean
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun JsBoolean.toBoolean(): Boolean = unsafeCast<Boolean>()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun Boolean.toJsBoolean(): JsBoolean = unsafeCast<JsBoolean>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsError.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsError.kt
new file mode 100644
index 0000000..2b76171
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsError.kt
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsError = Throwable
+
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsException.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsException.kt
new file mode 100644
index 0000000..5c0c457
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsException.kt
@@ -0,0 +1,19 @@
+@file:Suppress("EXPECT_ACTUAL_INCOMPATIBLE_SUPERTYPES")
+package kotlin.js
+
+/**
+ * A wrapper for an exception thrown by a JavaScript code.
+ * All exceptions thrown by JS code are signalled to Wasm code as `JsException`.
+ * */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsException = Throwable
+
+/**
+ *
+ * @property thrownValue value thrown by JavaScript; commonly it's an instance of an `Error` or its subclass, but it can be any JavaScript value
+ * */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline val JsException.thrownValue: JsAny?
+    get() = unsafeCast<JsAny?>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsNumber.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsNumber.kt
new file mode 100644
index 0000000..a0e7842
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsNumber.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive number */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsNumber = Double
+
+@Suppress("NOTHING_TO_INLINE")
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun JsNumber.toDouble(): Double = unsafeCast<Double>()
+
+@Suppress("NOTHING_TO_INLINE")
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun Double.toJsNumber(): JsNumber = unsafeCast<JsNumber>()
+
+@Suppress("NOTHING_TO_INLINE")
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun JsNumber.toInt(): Int = unsafeCast<Int>()
+
+@Suppress("NOTHING_TO_INLINE")
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun Int.toJsNumber(): JsNumber = unsafeCast<JsNumber>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsReference.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsReference.kt
new file mode 100644
index 0000000..56a2501
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsReference.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+@file:Suppress("ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION", "EXPECT_ACTUAL_INCOMPATIBLE_CLASS_TYPE_PARAMETER_COUNT")
+package kotlin.js
+
+// TODO: Replace `Any` with `T` as soon as it will be possible
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsReference<T> = Any
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : Any> T.toJsReference(): JsReference<T> = unsafeCast<JsReference<T>>()
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+@Suppress("NOTHING_TO_INLINE")
+public actual inline fun <T : Any> JsReference<T>.get(): T = unsafeCast<T>()
diff --git a/libraries/stdlib/js/src/kotlin/wasmJs/JsString.kt b/libraries/stdlib/js/src/kotlin/wasmJs/JsString.kt
new file mode 100644
index 0000000..6dd8b39
--- /dev/null
+++ b/libraries/stdlib/js/src/kotlin/wasmJs/JsString.kt
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive string */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual typealias JsString = String
+
+@Suppress("NOTHING_TO_INLINE")
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public actual inline fun String.toJsString(): JsString = this
diff --git a/libraries/stdlib/wasm/js/src/kotlin/JsInterop.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/JsInterop.kt
similarity index 93%
rename from libraries/stdlib/wasm/js/src/kotlin/JsInterop.kt
rename to libraries/stdlib/jsAndWasmJsCommon/src/kotlin/JsInterop.kt
index 0ee8525..6052ba2 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/JsInterop.kt
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/JsInterop.kt
@@ -5,6 +5,8 @@
 
 package kotlin
 
+import kotlin.js.ExperimentalWasmJsInterop
+
 /**
  * Implements annotated function in JavaScript and automatically imports is to Wasm.
  * [code] string must contain JS expression that evaluates to JS function with signature that matches annotated kotlin function
@@ -18,6 +20,7 @@
  * This is a temporary annotation because K/Wasm <-> JS interop is not designed yet.
  */
 @ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
 @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
 @Retention(AnnotationRetention.BINARY)
 public annotation class JsFun(val code: String)
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsAny.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsAny.kt
new file mode 100644
index 0000000..2db8ecc
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsAny.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/**
+ * Any JavaScript value except null or undefined for WasmJs interop
+ */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect interface JsAny
+
+/**
+ * Cast JsAny to other Js type without runtime check for WasmJs interop
+ */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T : JsAny> JsAny.unsafeCast(): T
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsArray.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsArray.kt
new file mode 100644
index 0000000..99e1baf
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsArray.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript Array for WasmJs Interop */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect class JsArray<T : JsAny?> : JsAny
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T: JsAny?> JsArray(): JsArray<T>
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect val JsArray<*>.length: Int
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect operator fun <T : JsAny?> JsArray<T>.get(index: Int): T?
+
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect operator fun <T : JsAny?> JsArray<T>.set(index: Int, value: T)
+
+/** Returns a new [Array] containing all the elements of this [JsArray]. */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T : JsAny?> JsArray<T>.toArray(): Array<T>
+
+/** Returns a new [JsArray] containing all the elements of this [Array]. */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T : JsAny?> Array<T>.toJsArray(): JsArray<T>
+
+/** Returns a new [List] containing all the elements of this [JsArray]. */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T : JsAny?> JsArray<T>.toList(): List<T>
+
+/** Returns a new [JsArray] containing all the elements of this [List]. */
+@SinceKotlin("2.2")
+@ExperimentalWasmJsInterop
+public expect fun <T : JsAny?> List<T>.toJsArray(): JsArray<T>
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBigInt.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBigInt.kt
new file mode 100644
index 0000000..e2e34ec
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBigInt.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive bigint for WasmJs interop */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class JsBigInt : JsAny
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun JsBigInt.toLong(): Long
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun Long.toJsBigInt(): JsBigInt
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBoolean.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBoolean.kt
new file mode 100644
index 0000000..36fc1bb
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsBoolean.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive boolean for WasmJs interop */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class JsBoolean : JsAny
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun JsBoolean.toBoolean(): Boolean
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun Boolean.toJsBoolean(): JsBoolean
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsError.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsError.kt
new file mode 100644
index 0000000..2c6c1a8
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsError.kt
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class JsError : JsAny
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsException.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsException.kt
new file mode 100644
index 0000000..b3f4a07
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsException.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+package kotlin.js
+
+/**
+ * A wrapper for an exception thrown by a JavaScript code.
+ * All exceptions thrown by JS code are signalled to Wasm code as `JsException`.
+ *
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+@Suppress("EXPECT_ACTUAL_IR_INCOMPATIBILITY")
+public expect class JsException : Throwable
+
+/**
+ * @property thrownValue value thrown by JavaScript; commonly it's an instance of an `Error` or its subclass, but it can be any JavaScript value
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect val JsException.thrownValue: JsAny?
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsNumber.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsNumber.kt
new file mode 100644
index 0000000..4288dc7
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsNumber.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive number for WasmJs interop */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class JsNumber : JsAny
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun JsNumber.toDouble(): Double
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun Double.toJsNumber(): JsNumber
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun JsNumber.toInt(): Int
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun Int.toJsNumber(): JsNumber
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsReference.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsReference.kt
new file mode 100644
index 0000000..eb975e2
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsReference.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+package kotlin.js
+
+/**
+ * JavaScript value that can serve as a reference for any Kotlin value.
+ *
+ * In JavaScript, it behaves like an immutable empty object with a null prototype.
+ * When passed back to Kotlin/Wasm, the original value can be retrieved using the [get] method.
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+@Suppress("EXPECT_ACTUAL_IR_INCOMPATIBILITY")
+public expect sealed interface JsReference<out T : Any> : JsAny
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun <T : Any> T.toJsReference(): JsReference<T>
+
+/** Retrieve original Kotlin value from JsReference */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun <T : Any> JsReference<T>.get(): T
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsString.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsString.kt
new file mode 100644
index 0000000..5e34a3b
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/JsString.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/** JavaScript primitive string for WasmJs interop */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class JsString : JsAny
+
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun String.toJsString(): JsString
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/Promise.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/Promise.kt
new file mode 100644
index 0000000..b31f166
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/Promise.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+import kotlin.internal.LowPriorityInOverloadResolution
+
+/**
+ * Exposes the JavaScript [Promise object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) to Kotlin.
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect class Promise<out T : JsAny?>(executor: (resolve: (T) -> Unit, reject: (JsError) -> Unit) -> Unit): JsAny {
+    @LowPriorityInOverloadResolution
+    public fun <S : JsAny?> then(onFulfilled: ((T) -> S)?): Promise<S>
+
+    @LowPriorityInOverloadResolution
+    public fun <S : JsAny?> then(onFulfilled: ((T) -> S)?, onRejected: ((JsError) -> S)?): Promise<S>
+
+    public fun <S : JsAny?> catch(onRejected: (JsError) -> S): Promise<S>
+    public fun finally(onFinally: () -> Unit): Promise<T>
+
+    public companion object {
+        public fun <S : JsAny?> all(promise: JsArray<out Promise<S>>): Promise<JsArray<out S>>
+        public fun <S : JsAny?> race(promise: JsArray<out Promise<S>>): Promise<S>
+        public fun reject(e: JsError): Promise<Nothing>
+        public fun <S : JsAny?> resolve(e: S): Promise<S>
+        public fun <S : JsAny?> resolve(e: Promise<S>): Promise<S>
+    }
+}
\ No newline at end of file
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/annotations.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/annotations.kt
new file mode 100644
index 0000000..acd44af
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/annotations.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/**
+ * Marks API related to interoperability with JS as experimental.
+ *
+ * Note that the behavior of such API may be changed in the future.
+ *
+ * Usages of such API will be reported as warnings unless an explicit opt-in with
+ * the [OptIn] annotation, e.g. `@OptIn(ExperimentalWasmJsInterop::class)`,
+ * or with the `-opt-in=kotlin.js.ExperimentalWasmJsInterop` compiler option is given.
+ */
+@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
+@MustBeDocumented
+@Retention(AnnotationRetention.BINARY)
+@SinceKotlin("2.2")
+@Target(
+    AnnotationTarget.CLASS,
+    AnnotationTarget.FUNCTION,
+    AnnotationTarget.PROPERTY,
+    AnnotationTarget.TYPEALIAS
+)
+public annotation class ExperimentalWasmJsInterop
+
+/**
+ * Denotes an `external` declaration that must be imported from JavaScript module.
+ *
+ * The annotation can be used on top-level external declarations (classes, properties, functions) and files.
+ * In case of file (which can't be `external`) the following rule applies: all the declarations in
+ * the file must be `external`. By applying `@JsModule(...)` on a file you tell the compiler to import a JavaScript object
+ * that contains all the declarations from the file.
+ *
+ * Example:
+ *
+ * ```kotlin
+ * @JsModule("jquery")
+ * external abstract class JQuery() {
+ *     // some declarations here
+ * }
+ *
+ * @JsModule("jquery")
+ * external fun JQuery(element: Element): JQuery
+ * ```
+ *
+ * @property import name of a module to import declaration from.
+ *           It is not interpreted by the Kotlin compiler, it's passed as is directly to the target module system.
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.FILE)
+public expect annotation class JsModule(val import: String)
+
+/**
+ * Adds prefix to `external` declarations in a source file.
+ *
+ * JavaScript does not have a concept of packages (namespaces). They are usually emulated by nested objects.
+ * The compiler turns references to `external` declarations either to plain unprefixed names
+ * or to plain imports.
+ * However, if a JavaScript library provides its declarations in packages, you won't be satisfied with this.
+ * You can tell the compiler to generate additional prefix before references to `external` declarations using the `@JsQualifier(...)`
+ * annotation.
+ *
+ * Note that a file marked with the `@JsQualifier(...)` annotation can't contain non-`external` declarations.
+ *
+ * Example:
+ *
+ * ```
+ * @file:JsQualifier("my.jsPackageName")
+ * package some.kotlinPackage
+ *
+ * external fun foo(x: Int)
+ *
+ * external fun bar(): String
+ * ```
+ *
+ * @property value the qualifier to add to the declarations in the generated code.
+ *           It must be a sequence of valid JavaScript identifiers separated by the `.` character.
+ *           Examples of valid qualifiers are: `foo`, `bar.Baz`, `_.$0.f`.
+ *
+ * @see JsModule
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.FILE)
+public expect annotation class JsQualifier(val value: String)
diff --git a/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/core.kt b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/core.kt
new file mode 100644
index 0000000..65780f3
--- /dev/null
+++ b/libraries/stdlib/jsAndWasmJsCommon/src/kotlin/js/core.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+/**
+ * The property that can be used as a placeholder for statements and values that are defined in JavaScript.
+ *
+ * This property can be used in two cases:
+ *
+ *   * To represent the body of an external function. In most cases Kotlin does not require to provide bodies of external
+ *     functions and properties, but if for some reason you want to (for example, due to limitation of your coding style guides),
+ *     you should use `definedExternally`.
+ *   * To represent the value of default argument.
+ *
+ * There's two forms of using `definedExternally`:
+ *
+ *   1. `= definedExternally` (for functions, properties, and parameters).
+ *   2. `{ definedExternally }` (for functions and property getters/setters).
+ *
+ * This property can't be used from normal code.
+ *
+ * Examples:
+ *
+ * ```kotlin
+ * external fun foo(): String = definedExternally
+ * external fun bar(x: Int) { definedExternally }
+ * external fun baz(z: Any = definedExternally): Array<Any>
+ * external val prop: Float = definedExternally
+ * ```
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect val definedExternally: Nothing
+
+/**
+ * This function allows you to incorporate JavaScript [code] into Kotlin/Wasm and/or Kotlin/JS codebase.
+ * It is used to implement top-level functions and initialize top-level properties.
+ *
+ * It is important to note that calls to the [js] function should be the only expression
+ * in a function body or a property initializer.
+ *
+ * [code] parameter should be a compile-time constant.
+ *
+ * When used in an expression context, [code] should contain a single JavaScript expression. For example:
+ *
+ * ```kotlin
+ * val version: String = js("process.version")
+ * fun newEmptyJsArray(): JsValue = js("[]")
+ * ```
+ *
+ * When used in a function body, [code] is expected to be a list of JavaScript statements. For example:
+ *
+ * ```kotlin
+ * fun log(message1: String, message2: String) {
+ *     js("""
+ *     console.log(message1);
+ *     console.log(message2);
+ *     """)
+ * }
+ * ```
+ *
+ * You can use parameters of calling function in JavaScript [code].
+ * However, other Kotlin declarations are not visible inside the [code] block.
+ */
+@ExperimentalWasmJsInterop
+@SinceKotlin("2.2")
+public expect fun js(code: String): Nothing
\ No newline at end of file
diff --git a/libraries/stdlib/kotlin-project-structure-metadata.beforePatch.json b/libraries/stdlib/kotlin-project-structure-metadata.beforePatch.json
index 1c51e32..8ab7639 100644
--- a/libraries/stdlib/kotlin-project-structure-metadata.beforePatch.json
+++ b/libraries/stdlib/kotlin-project-structure-metadata.beforePatch.json
@@ -6,15 +6,17 @@
       {
         "name": "jsApiElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
         "name": "jsRuntimeElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
@@ -32,15 +34,17 @@
       {
         "name": "wasmJsApiElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
         "name": "wasmJsRuntimeElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
@@ -72,6 +76,14 @@
         ],
         "moduleDependency": [],
         "binaryLayout": "klib"
+      },
+      {
+        "name": "webMain",
+        "dependsOn": [
+          "commonMain"
+        ],
+        "moduleDependency": [],
+        "binaryLayout": "klib"
       }
     ]
   }
diff --git a/libraries/stdlib/kotlin-project-structure-metadata.json b/libraries/stdlib/kotlin-project-structure-metadata.json
index 56fdcd2..8ab7639 100644
--- a/libraries/stdlib/kotlin-project-structure-metadata.json
+++ b/libraries/stdlib/kotlin-project-structure-metadata.json
@@ -6,15 +6,17 @@
       {
         "name": "jsApiElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
         "name": "jsRuntimeElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
@@ -30,24 +32,19 @@
         ]
       },
       {
-        "name": "nativeApiElements",
-        "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
-        ]
-      },
-      {
         "name": "wasmJsApiElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
         "name": "wasmJsRuntimeElements",
         "sourceSet": [
-          "commonNonJvmMain",
-          "commonMain"
+          "webMain",
+          "commonMain",
+          "commonNonJvmMain"
         ]
       },
       {
@@ -79,6 +76,14 @@
         ],
         "moduleDependency": [],
         "binaryLayout": "klib"
+      },
+      {
+        "name": "webMain",
+        "dependsOn": [
+          "commonMain"
+        ],
+        "moduleDependency": [],
+        "binaryLayout": "klib"
       }
     ]
   }
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsAny.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsAny.kt
index d76e0d0..83789d2 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsAny.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsAny.kt
@@ -13,7 +13,7 @@
  * Any JavaScript value except null or undefined
  */
 @ExperimentalWasmJsInterop
-public external interface JsAny
+public actual external interface JsAny
 
 /**
  * Cast JsAny to other Js type without runtime check
@@ -21,5 +21,5 @@
 @WasmNoOpCast
 @ExcludedFromCodegen
 @ExperimentalWasmJsInterop
-public fun <T : JsAny> JsAny.unsafeCast(): T =
+public actual fun <T : JsAny> JsAny.unsafeCast(): T =
     implementedAsIntrinsic
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsArray.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsArray.kt
index b93f7aa..c6685d1 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsArray.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsArray.kt
@@ -5,19 +5,30 @@
 
 package kotlin.js
 
+import kotlin.internal.LowPriorityInOverloadResolution
+
 /** JavaScript Array */
 @ExperimentalWasmJsInterop
 @JsName("Array")
-public external class JsArray<T : JsAny?> : JsAny {
+public actual external class JsArray<T : JsAny?> : JsAny {
     public val length: Int
 }
 
 @ExperimentalWasmJsInterop
-public operator fun <T : JsAny?> JsArray<T>.get(index: Int): T? =
+@LowPriorityInOverloadResolution
+public actual fun <T : JsAny?> JsArray(): JsArray<T> =
+    JsArray()
+
+@ExperimentalWasmJsInterop
+public actual val JsArray<*>.length: Int
+    inline get() = length
+
+@ExperimentalWasmJsInterop
+public actual operator fun <T : JsAny?> JsArray<T>.get(index: Int): T? =
     jsArrayGet(this, index)
 
 @ExperimentalWasmJsInterop
-public operator fun <T : JsAny?> JsArray<T>.set(index: Int, value: T) {
+public actual operator fun <T : JsAny?> JsArray<T>.set(index: Int, value: T) {
     jsArraySet(this, index, value)
 }
 
@@ -34,14 +45,14 @@
 
 /** Returns a new [Array] containing all the elements of this [JsArray]. */
 @ExperimentalWasmJsInterop
-public fun <T : JsAny?> JsArray<T>.toArray(): Array<T> {
+public actual fun <T : JsAny?> JsArray<T>.toArray(): Array<T> {
     @Suppress("UNCHECKED_CAST", "TYPE_PARAMETER_AS_REIFIED")
     return Array(this.length) { this[it] as T }
 }
 
 /** Returns a new [JsArray] containing all the elements of this [Array]. */
 @ExperimentalWasmJsInterop
-public fun <T : JsAny?> Array<T>.toJsArray(): JsArray<T> {
+public actual fun <T : JsAny?> Array<T>.toJsArray(): JsArray<T> {
     val destination = JsArray<T>()
     for (i in this.indices) {
         destination[i] = this[i]
@@ -51,14 +62,14 @@
 
 /** Returns a new [List] containing all the elements of this [JsArray]. */
 @ExperimentalWasmJsInterop
-public fun <T : JsAny?> JsArray<T>.toList(): List<T> {
+public actual fun <T : JsAny?> JsArray<T>.toList(): List<T> {
     @Suppress("UNCHECKED_CAST")
     return List(length) { this[it] as T }
 }
 
 /** Returns a new [JsArray] containing all the elements of this [List]. */
 @ExperimentalWasmJsInterop
-public fun <T : JsAny?> List<T>.toJsArray(): JsArray<T> {
+public actual fun <T : JsAny?> List<T>.toJsArray(): JsArray<T> {
     val destination = JsArray<T>()
     for (i in this.indices) {
         destination[i] = this[i]
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt
index 10b94de..2207cf6 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt
@@ -11,12 +11,12 @@
 /** JavaScript primitive bigint */
 @JsPrimitive("bigint")
 @ExperimentalWasmJsInterop
-public external class JsBigInt internal constructor() : JsAny
+public actual external class JsBigInt internal constructor() : JsAny
 
 @ExperimentalWasmJsInterop
-public fun JsBigInt.toLong(): Long =
+public actual fun JsBigInt.toLong(): Long =
     externRefToKotlinLongAdapter(this)
 
 @ExperimentalWasmJsInterop
-public fun Long.toJsBigInt(): JsBigInt =
+public actual fun Long.toJsBigInt(): JsBigInt =
     kotlinLongToExternRefAdapter(this)
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsBoolean.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsBoolean.kt
index c3a0d70..22ea53b 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsBoolean.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsBoolean.kt
@@ -12,12 +12,12 @@
 /** JavaScript primitive boolean */
 @JsPrimitive("boolean")
 @ExperimentalWasmJsInterop
-public external class JsBoolean internal constructor() : JsAny
+public actual external class JsBoolean internal constructor() : JsAny
 
 @ExperimentalWasmJsInterop
-public fun JsBoolean.toBoolean(): Boolean =
+public actual fun JsBoolean.toBoolean(): Boolean =
     externRefToKotlinBooleanAdapter(this)
 
 @ExperimentalWasmJsInterop
-public fun Boolean.toJsBoolean(): JsBoolean =
+public actual fun Boolean.toJsBoolean(): JsBoolean =
     kotlinBooleanToExternRefAdapter(this)
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsError.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsError.kt
new file mode 100644
index 0000000..6be0819
--- /dev/null
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsError.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package kotlin.js
+
+import kotlin.wasm.internal.ExternalInterfaceType
+
+@SinceKotlin("2.2")
+@JsName("Error")
+@ExperimentalWasmJsInterop
+public actual external class JsError : JsAny {
+    internal val message: String
+    internal var name: String
+    internal val stack: ExternalInterfaceType
+    internal val cause: JsError?
+    internal var kotlinException: JsReference<Throwable>?
+}
+
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsException.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsException.kt
index 2b64a94..fedd561 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsException.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsException.kt
@@ -15,11 +15,11 @@
  * All exceptions thrown by JS code are signalled to Wasm code as `JsException`.
  *
  * @property thrownValue value thrown by JavaScript; commonly it's an instance of an `Error` or its subclass, but it can be any JavaScript value
- */
+ * */
 @ExperimentalWasmJsInterop
-public class JsException internal constructor(public val thrownValue: JsAny?) : Throwable(null, null, null) {
+public actual class JsException internal constructor(public val thrownValue: JsAny?) : Throwable(null, null, null) {
     private var _message: String? = null
-    override val message: String
+    override val message: String?
         get() {
             var value = _message
             if (value == null) {
@@ -41,12 +41,5 @@
         }
 }
 
-@OptIn(ExperimentalWasmJsInterop::class)
-@JsName("Error")
-internal external class JsError : JsAny {
-    val message: String
-    var name: String
-    val stack: ExternalInterfaceType
-    val cause: JsError?
-    var kotlinException: JsReference<Throwable>?
-}
+@ExperimentalWasmJsInterop
+public actual val JsException.thrownValue: JsAny? get() = this.thrownValue
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsNumber.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsNumber.kt
index 3c345cd..28d812e 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsNumber.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsNumber.kt
@@ -14,20 +14,20 @@
 /** JavaScript primitive number */
 @JsPrimitive("number")
 @ExperimentalWasmJsInterop
-public external class JsNumber internal constructor() : JsAny
+public actual external class JsNumber internal constructor() : JsAny
 
 @ExperimentalWasmJsInterop
-public fun JsNumber.toDouble(): Double =
+public actual fun JsNumber.toDouble(): Double =
     externRefToKotlinDoubleAdapter(this)
 
 @ExperimentalWasmJsInterop
-public fun Double.toJsNumber(): JsNumber =
+public actual fun Double.toJsNumber(): JsNumber =
     kotlinDoubleToExternRefAdapter(this)
 
 @ExperimentalWasmJsInterop
-public fun JsNumber.toInt(): Int =
+public actual fun JsNumber.toInt(): Int =
     externRefToKotlinIntAdapter(this)
 
 @ExperimentalWasmJsInterop
-public fun Int.toJsNumber(): JsNumber =
+public actual fun Int.toJsNumber(): JsNumber =
     kotlinIntToExternRefAdapter(this)
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsReference.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsReference.kt
index 7df2d19..05a9165 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsReference.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsReference.kt
@@ -17,16 +17,16 @@
  */
 @Suppress("WRONG_JS_INTEROP_TYPE")  // Exception to the rule
 @ExperimentalWasmJsInterop
-public sealed external interface JsReference<out T : Any> : JsAny
+public actual sealed external interface JsReference<out T : Any> : JsAny
 
 @WasmOp(WasmOp.EXTERN_EXTERNALIZE)
 @ExperimentalWasmJsInterop
-public fun <T : Any> T.toJsReference(): JsReference<T> =
+public actual fun <T : Any> T.toJsReference(): JsReference<T> =
     implementedAsIntrinsic
 
 /** Retrieve original Kotlin value from JsReference */
 @ExperimentalWasmJsInterop
-public fun <T : Any> JsReference<T>.get(): T {
+public actual fun <T : Any> JsReference<T>.get(): T {
     returnArgumentIfItIsKotlinAny()
     throw ClassCastException("JsReference doesn't contain a Kotlin type")
 }
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsString.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsString.kt
index 7c4a914..21ec77f 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/JsString.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsString.kt
@@ -11,8 +11,8 @@
 /** JavaScript primitive string */
 @JsPrimitive("string")
 @ExperimentalWasmJsInterop
-public external class JsString internal constructor() : JsAny
+public actual external class JsString internal constructor() : JsAny
 
 @ExperimentalWasmJsInterop
-public fun String.toJsString(): JsString =
+public actual fun String.toJsString(): JsString =
     kotlinToJsStringAdapter(this)!!
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/Promise.kt b/libraries/stdlib/wasm/js/src/kotlin/js/Promise.kt
index af38ee5..5c56e9c 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/Promise.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/Promise.kt
@@ -11,21 +11,41 @@
  * Exposes the JavaScript [Promise object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) to Kotlin.
  */
 @ExperimentalWasmJsInterop
-public external class Promise<out T : JsAny?>(executor: (resolve: (T) -> Unit, reject: (JsAny) -> Unit) -> Unit) : JsAny {
+public actual external class Promise<out T : JsAny?>
+@SinceKotlin("2.2")
+@LowPriorityInOverloadResolution
+actual constructor(executor: (resolve: (T) -> Unit, reject: (JsError) -> Unit) -> Unit) : JsAny {
+
+    public constructor(executor: (resolve: (T) -> Unit, reject: (JsAny) -> Unit) -> Unit)
+
     @LowPriorityInOverloadResolution
-    public fun <S : JsAny?> then(onFulfilled: ((T) -> S)?): Promise<S>
+    public actual fun <S : JsAny?> then(onFulfilled: ((T) -> S)?): Promise<S>
+
+    @SinceKotlin("2.2")
+    @LowPriorityInOverloadResolution
+    public actual fun <S : JsAny?> then(onFulfilled: ((T) -> S)?, onRejected: ((JsError) -> S)?): Promise<S>
 
     @LowPriorityInOverloadResolution
     public fun <S : JsAny?> then(onFulfilled: ((T) -> S)?, onRejected: ((JsAny) -> S)?): Promise<S>
 
-    public fun <S : JsAny?> catch(onRejected: (JsAny) -> S): Promise<S>
-    public fun finally(onFinally: () -> Unit): Promise<T>
+    @SinceKotlin("2.2")
+    @LowPriorityInOverloadResolution
+    public actual fun <S : JsAny?> catch(onRejected: (JsError) -> S): Promise<S>
 
-    public companion object {
-        public fun <S : JsAny?> all(promise: JsArray<out Promise<S>>): Promise<JsArray<out S>>
-        public fun <S : JsAny?> race(promise: JsArray<out Promise<S>>): Promise<S>
+    public fun <S : JsAny?> catch(onRejected: (JsAny) -> S): Promise<S>
+
+    public actual fun finally(onFinally: () -> Unit): Promise<T>
+
+    public actual companion object {
+        public actual fun <S : JsAny?> all(promise: JsArray<out Promise<S>>): Promise<JsArray<out S>>
+        public actual fun <S : JsAny?> race(promise: JsArray<out Promise<S>>): Promise<S>
+
+        @SinceKotlin("2.2")
+        @LowPriorityInOverloadResolution
+        public actual fun reject(e: JsError): Promise<Nothing>
         public fun reject(e: JsAny): Promise<Nothing>
-        public fun <S : JsAny?> resolve(e: S): Promise<S>
-        public fun <S : JsAny?> resolve(e: Promise<S>): Promise<S>
+
+        public actual fun <S : JsAny?> resolve(e: S): Promise<S>
+        public actual fun <S : JsAny?> resolve(e: Promise<S>): Promise<S>
     }
 }
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/annotations.kt b/libraries/stdlib/wasm/js/src/kotlin/js/annotations.kt
index 14e12a3..0920917 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/annotations.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/annotations.kt
@@ -6,21 +6,6 @@
 package kotlin.js
 
 /**
- * Marks API related to interoperability with JS as experimental.
- *
- * Note that the behavior of such API may be changed in the future.
- *
- * Usages of such API will be reported as warnings unless an explicit opt-in with
- * the [OptIn] annotation, e.g. `@OptIn(ExperimentalWasmJsInterop::class)`,
- * or with the `-opt-in=kotlin.js.ExperimentalWasmJsInterop` compiler option is given.
- */
-@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
-@MustBeDocumented
-@Retention(AnnotationRetention.BINARY)
-@SinceKotlin("2.2")
-public annotation class ExperimentalWasmJsInterop
-
-/**
  * Exports top-level declaration on JS platform.
  *
  * Can only be applied to top-level functions.
@@ -64,7 +49,7 @@
  * The annotation can be used on top-level external declarations (classes, properties, functions) and files.
  * In case of file (which can't be `external`) the following rule applies: all the declarations in
  * the file must be `external`. By applying `@JsModule(...)` on a file you tell the compiler to import a JavaScript object
- * that contain all the declarations from the file.
+ * that contains all the declarations from the file.
  *
  * Example:
  *
@@ -84,13 +69,13 @@
 @ExperimentalWasmJsInterop
 @Retention(AnnotationRetention.BINARY)
 @Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.FILE)
-public annotation class JsModule(val import: String)
+public actual annotation class JsModule(actual val import: String)
 
 
 /**
  * Adds prefix to `external` declarations in a source file.
  *
- * JavaScript does not have concept of packages (namespaces). They are usually emulated by nested objects.
+ * JavaScript does not have a concept of packages (namespaces). They are usually emulated by nested objects.
  * The compiler turns references to `external` declarations either to plain unprefixed names
  * or to plain imports.
  * However, if a JavaScript library provides its declarations in packages, you won't be satisfied with this.
@@ -119,4 +104,4 @@
 @ExperimentalWasmJsInterop
 @Retention(AnnotationRetention.BINARY)
 @Target(AnnotationTarget.FILE)
-public annotation class JsQualifier(val value: String)
+public actual annotation class JsQualifier(actual val value: String)
diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/core.kt b/libraries/stdlib/wasm/js/src/kotlin/js/core.kt
index 8c2014d..84316a5 100644
--- a/libraries/stdlib/wasm/js/src/kotlin/js/core.kt
+++ b/libraries/stdlib/wasm/js/src/kotlin/js/core.kt
@@ -36,7 +36,7 @@
 @ExperimentalWasmJsInterop
 @ExcludedFromCodegen
 @Suppress("WRONG_JS_INTEROP_TYPE")
-public external val definedExternally: Nothing
+public actual external val definedExternally: Nothing
 
 /**
  * This function allows you to incorporate JavaScript [code] into Kotlin/Wasm codebase.
@@ -71,4 +71,4 @@
 @ExperimentalWasmJsInterop
 @ExcludedFromCodegen
 @SinceKotlin("1.9")
-public external fun js(code: String): Nothing
+public actual external fun js(code: String): Nothing
diff --git a/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api b/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
index 65dbe70..1390ae1 100644
--- a/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
+++ b/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
@@ -13938,6 +13938,11 @@
 final inline fun <#A: kotlin/Any?> kotlin/emptyArray(): kotlin/Array<#A> // kotlin/emptyArray|emptyArray(){0§<kotlin.Any?>}[0]
 
 // Targets: [js, wasmJs]
+open annotation class kotlin.js/ExperimentalWasmJsInterop : kotlin/Annotation { // kotlin.js/ExperimentalWasmJsInterop|null[0]
+    constructor <init>() // kotlin.js/ExperimentalWasmJsInterop.<init>|<init>(){}[0]
+}
+
+// Targets: [js, wasmJs]
 open annotation class kotlin.js/JsExport : kotlin/Annotation { // kotlin.js/JsExport|null[0]
     constructor <init>() // kotlin.js/JsExport.<init>|<init>(){}[0]
 
@@ -13971,6 +13976,14 @@
 }
 
 // Targets: [js, wasmJs]
+open annotation class kotlin/JsFun : kotlin/Annotation { // kotlin/JsFun|null[0]
+    constructor <init>(kotlin/String) // kotlin/JsFun.<init>|<init>(kotlin.String){}[0]
+
+    final val code // kotlin/JsFun.code|{}code[0]
+        final fun <get-code>(): kotlin/String // kotlin/JsFun.code.<get-code>|<get-code>(){}[0]
+}
+
+// Targets: [js, wasmJs]
 final val kotlin.js/definedExternally // kotlin.js/definedExternally|{}definedExternally[0]
     final fun <get-definedExternally>(): kotlin/Nothing // kotlin.js/definedExternally.<get-definedExternally>|<get-definedExternally>(){}[0]
 
@@ -14616,6 +14629,14 @@
     final fun <#A1: kotlin/Any> (kotlin.js/JsClass<#A1>).<get-kotlin>(): kotlin.reflect/KClass<#A1> // kotlin.js/kotlin.<get-kotlin>|<get-kotlin>@kotlin.js.JsClass<0:0>(){0§<kotlin.Any>}[0]
 
 // Targets: [js]
+final val kotlin.js/length // kotlin.js/length|@kotlin.Array<*>{}length[0]
+    final inline fun (kotlin/Array<*>).<get-length>(): kotlin/Int // kotlin.js/length.<get-length>|<get-length>@kotlin.Array<*>(){}[0]
+
+// Targets: [js]
+final val kotlin.js/thrownValue // kotlin.js/thrownValue|@kotlin.Throwable{}thrownValue[0]
+    final inline fun (kotlin/Throwable).<get-thrownValue>(): kotlin/Any? // kotlin.js/thrownValue.<get-thrownValue>|<get-thrownValue>@kotlin.Throwable(){}[0]
+
+// Targets: [js]
 final val kotlin.js/undefined // kotlin.js/undefined|{}undefined[0]
     final fun <get-undefined>(): kotlin/Nothing? // kotlin.js/undefined.<get-undefined>|<get-undefined>(){}[0]
 
@@ -14656,6 +14677,12 @@
 final fun (kotlin/IntArray).kotlin.collections/elementAt(kotlin/Int): kotlin/Int // kotlin.collections/elementAt|elementAt@kotlin.IntArray(kotlin.Int){}[0]
 
 // Targets: [js]
+final fun (kotlin/Long).kotlin.js/toJsBigInt(): kotlin/Long // kotlin.js/toJsBigInt|toJsBigInt@kotlin.Long(){}[0]
+
+// Targets: [js]
+final fun (kotlin/Long).kotlin.js/toLong(): kotlin/Long // kotlin.js/toLong|toLong@kotlin.Long(){}[0]
+
+// Targets: [js]
 final fun (kotlin/LongArray).kotlin.collections/elementAt(kotlin/Int): kotlin/Long // kotlin.collections/elementAt|elementAt@kotlin.LongArray(kotlin.Int){}[0]
 
 // Targets: [js]
@@ -14893,6 +14920,12 @@
 final inline fun (kotlin/Any?).kotlin.js/asDynamic(): dynamic // kotlin.js/asDynamic|asDynamic@kotlin.Any?(){}[0]
 
 // Targets: [js]
+final inline fun (kotlin/Boolean).kotlin.js/toBoolean(): kotlin/Boolean // kotlin.js/toBoolean|toBoolean@kotlin.Boolean(){}[0]
+
+// Targets: [js]
+final inline fun (kotlin/Boolean).kotlin.js/toJsBoolean(): kotlin/Boolean // kotlin.js/toJsBoolean|toJsBoolean@kotlin.Boolean(){}[0]
+
+// Targets: [js]
 final inline fun (kotlin/BooleanArray).kotlin.collections/asList(): kotlin.collections/List<kotlin/Boolean> // kotlin.collections/asList|asList@kotlin.BooleanArray(){}[0]
 
 // Targets: [js]
@@ -14950,6 +14983,15 @@
 final inline fun (kotlin/CharArray).kotlin.collections/sort(noinline kotlin/Function2<kotlin/Char, kotlin/Char, kotlin/Int>) // kotlin.collections/sort|sort@kotlin.CharArray(kotlin.Function2<kotlin.Char,kotlin.Char,kotlin.Int>){}[0]
 
 // Targets: [js]
+final inline fun (kotlin/Double).kotlin.js/toDouble(): kotlin/Double // kotlin.js/toDouble|toDouble@kotlin.Double(){}[0]
+
+// Targets: [js]
+final inline fun (kotlin/Double).kotlin.js/toInt(): kotlin/Int // kotlin.js/toInt|toInt@kotlin.Double(){}[0]
+
+// Targets: [js]
+final inline fun (kotlin/Double).kotlin.js/toJsNumber(): kotlin/Double // kotlin.js/toJsNumber|toJsNumber@kotlin.Double(){}[0]
+
+// Targets: [js]
 final inline fun (kotlin/Double).kotlin.math/pow(kotlin/Double): kotlin/Double // kotlin.math/pow|pow@kotlin.Double(kotlin.Double){}[0]
 
 // Targets: [js]
@@ -15013,6 +15055,9 @@
 final inline fun (kotlin/FloatArray).kotlin.collections/sort(noinline kotlin/Function2<kotlin/Float, kotlin/Float, kotlin/Int>) // kotlin.collections/sort|sort@kotlin.FloatArray(kotlin.Function2<kotlin.Float,kotlin.Float,kotlin.Int>){}[0]
 
 // Targets: [js]
+final inline fun (kotlin/Int).kotlin.js/toJsNumber(): kotlin/Double // kotlin.js/toJsNumber|toJsNumber@kotlin.Int(){}[0]
+
+// Targets: [js]
 final inline fun (kotlin/Int).kotlin/countLeadingZeroBits(): kotlin/Int // kotlin/countLeadingZeroBits|countLeadingZeroBits@kotlin.Int(){}[0]
 
 // Targets: [js]
@@ -15067,6 +15112,9 @@
 final inline fun (kotlin/ShortArray).kotlin.collections/sort(noinline kotlin/Function2<kotlin/Short, kotlin/Short, kotlin/Int>) // kotlin.collections/sort|sort@kotlin.ShortArray(kotlin.Function2<kotlin.Short,kotlin.Short,kotlin.Int>){}[0]
 
 // Targets: [js]
+final inline fun (kotlin/String).kotlin.js/toJsString(): kotlin/String // kotlin.js/toJsString|toJsString@kotlin.String(){}[0]
+
+// Targets: [js]
 final inline fun (kotlin/String).kotlin.text/concat(kotlin/String): kotlin/String // kotlin.text/concat|concat@kotlin.String(kotlin.String){}[0]
 
 // Targets: [js]
@@ -15094,6 +15142,15 @@
 final inline fun /withType(kotlin/String, dynamic): dynamic // /withType|withType(kotlin.String;<dynamic>){}[0]
 
 // Targets: [js]
+final inline fun <#A: kotlin/Any> (#A).kotlin.js/toJsReference(): kotlin/Any // kotlin.js/toJsReference|toJsReference@0:0(){0§<kotlin.Any>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any> (kotlin/Any).kotlin.js/get(): #A // kotlin.js/get|get@kotlin.Any(){0§<kotlin.Any>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any> (kotlin/Any).kotlin.js/unsafeCast(): #A // kotlin.js/unsafeCast|unsafeCast@kotlin.Any(){0§<kotlin.Any>}[0]
+
+// Targets: [js]
 final inline fun <#A: kotlin/Any?, #B: kotlin/Any?> (kotlin.js.collections/JsReadonlyMap<#A, #B>).kotlin.js.collections/toMap(): kotlin.collections/Map<#A, #B> // kotlin.js.collections/toMap|toMap@kotlin.js.collections.JsReadonlyMap<0:0,0:1>(){0§<kotlin.Any?>;1§<kotlin.Any?>}[0]
 
 // Targets: [js]
@@ -15112,6 +15169,9 @@
 final inline fun <#A: kotlin/Any?> (dynamic).kotlin.js/unsafeCast(): #A // kotlin.js/unsafeCast|unsafeCast@<dynamic>(){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin.collections/List<#A>).kotlin.js/toJsArray(): kotlin/Array<#A> // kotlin.js/toJsArray|toJsArray@kotlin.collections.List<0:0>(){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
 final inline fun <#A: kotlin/Any?> (kotlin.js.collections/JsReadonlyArray<#A>).kotlin.js.collections/toList(): kotlin.collections/List<#A> // kotlin.js.collections/toList|toList@kotlin.js.collections.JsReadonlyArray<0:0>(){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
@@ -15145,6 +15205,21 @@
 final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.collections/plus(kotlin/Array<out #A>): kotlin/Array<#A> // kotlin.collections/plus|plus@kotlin.Array<0:0>(kotlin.Array<out|0:0>){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.js/get(kotlin/Int): #A? // kotlin.js/get|get@kotlin.Array<0:0>(kotlin.Int){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.js/set(kotlin/Int, #A) // kotlin.js/set|set@kotlin.Array<0:0>(kotlin.Int;0:0){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.js/toArray(): kotlin/Array<#A> // kotlin.js/toArray|toArray@kotlin.Array<0:0>(){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.js/toJsArray(): kotlin/Array<#A> // kotlin.js/toJsArray|toJsArray@kotlin.Array<0:0>(){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
+final inline fun <#A: kotlin/Any?> (kotlin/Array<#A>).kotlin.js/toList(): kotlin.collections/List<#A> // kotlin.js/toList|toList@kotlin.Array<0:0>(){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
 final inline fun <#A: kotlin/Any?> (kotlin/Array<out #A>).kotlin.collections/copyInto(kotlin/Array<#A>, kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): kotlin/Array<#A> // kotlin.collections/copyInto|copyInto@kotlin.Array<out|0:0>(kotlin.Array<0:0>;kotlin.Int;kotlin.Int;kotlin.Int){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
@@ -15166,6 +15241,9 @@
 final inline fun <#A: kotlin/Any?> kotlin.collections/linkedSetOf(): kotlin.collections/LinkedHashSet<#A> // kotlin.collections/linkedSetOf|linkedSetOf(){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
+final inline fun <#A: kotlin/Any?> kotlin.js/JsArray(): kotlin/Array<#A> // kotlin.js/JsArray|JsArray(){0§<kotlin.Any?>}[0]
+
+// Targets: [js]
 final inline fun <#A: kotlin/Any?> kotlin/synchronized(kotlin/Any, kotlin/Function0<#A>): #A // kotlin/synchronized|synchronized(kotlin.Any;kotlin.Function0<0:0>){0§<kotlin.Any?>}[0]
 
 // Targets: [js]
@@ -15373,19 +15451,6 @@
 final suspend inline fun kotlin.js/getCoroutineContext(): kotlin.coroutines/CoroutineContext // kotlin.js/getCoroutineContext|getCoroutineContext(){}[0]
 
 // Targets: [wasmJs]
-open annotation class kotlin.js/ExperimentalWasmJsInterop : kotlin/Annotation { // kotlin.js/ExperimentalWasmJsInterop|null[0]
-    constructor <init>() // kotlin.js/ExperimentalWasmJsInterop.<init>|<init>(){}[0]
-}
-
-// Targets: [wasmJs]
-open annotation class kotlin/JsFun : kotlin/Annotation { // kotlin/JsFun|null[0]
-    constructor <init>(kotlin/String) // kotlin/JsFun.<init>|<init>(kotlin.String){}[0]
-
-    final val code // kotlin/JsFun.code|{}code[0]
-        final fun <get-code>(): kotlin/String // kotlin/JsFun.code.<get-code>|<get-code>(){}[0]
-}
-
-// Targets: [wasmJs]
 abstract interface kotlin.js/Dynamic : kotlin.js/JsAny // kotlin.js/Dynamic|null[0]
 
 // Targets: [wasmJs]
@@ -15405,10 +15470,13 @@
 // Targets: [wasmJs]
 final class <#A: out kotlin.js/JsAny?> kotlin.js/Promise : kotlin.js/JsAny { // kotlin.js/Promise|null[0]
     constructor <init>(kotlin/Function2<kotlin/Function1<#A, kotlin/Unit>, kotlin/Function1<kotlin.js/JsAny, kotlin/Unit>, kotlin/Unit>) // kotlin.js/Promise.<init>|<init>(kotlin.Function2<kotlin.Function1<1:0,kotlin.Unit>,kotlin.Function1<kotlin.js.JsAny,kotlin.Unit>,kotlin.Unit>){}[0]
+    constructor <init>(kotlin/Function2<kotlin/Function1<#A, kotlin/Unit>, kotlin/Function1<kotlin.js/JsError, kotlin/Unit>, kotlin/Unit>) // kotlin.js/Promise.<init>|<init>(kotlin.Function2<kotlin.Function1<1:0,kotlin.Unit>,kotlin.Function1<kotlin.js.JsError,kotlin.Unit>,kotlin.Unit>){}[0]
 
     final fun <#A1: kotlin.js/JsAny?> catch(kotlin/Function1<kotlin.js/JsAny, #A1>): kotlin.js/Promise<#A1> // kotlin.js/Promise.catch|catch(kotlin.Function1<kotlin.js.JsAny,0:0>){0§<kotlin.js.JsAny?>}[0]
+    final fun <#A1: kotlin.js/JsAny?> catch(kotlin/Function1<kotlin.js/JsError, #A1>): kotlin.js/Promise<#A1> // kotlin.js/Promise.catch|catch(kotlin.Function1<kotlin.js.JsError,0:0>){0§<kotlin.js.JsAny?>}[0]
     final fun <#A1: kotlin.js/JsAny?> then(kotlin/Function1<#A, #A1>?): kotlin.js/Promise<#A1> // kotlin.js/Promise.then|then(kotlin.Function1<1:0,0:0>?){0§<kotlin.js.JsAny?>}[0]
     final fun <#A1: kotlin.js/JsAny?> then(kotlin/Function1<#A, #A1>?, kotlin/Function1<kotlin.js/JsAny, #A1>?): kotlin.js/Promise<#A1> // kotlin.js/Promise.then|then(kotlin.Function1<1:0,0:0>?;kotlin.Function1<kotlin.js.JsAny,0:0>?){0§<kotlin.js.JsAny?>}[0]
+    final fun <#A1: kotlin.js/JsAny?> then(kotlin/Function1<#A, #A1>?, kotlin/Function1<kotlin.js/JsError, #A1>?): kotlin.js/Promise<#A1> // kotlin.js/Promise.then|then(kotlin.Function1<1:0,0:0>?;kotlin.Function1<kotlin.js.JsError,0:0>?){0§<kotlin.js.JsAny?>}[0]
     final fun finally(kotlin/Function0<kotlin/Unit>): kotlin.js/Promise<#A> // kotlin.js/Promise.finally|finally(kotlin.Function0<kotlin.Unit>){}[0]
 
     final object Companion { // kotlin.js/Promise.Companion|null[0]
@@ -15417,6 +15485,7 @@
         final fun <#A2: kotlin.js/JsAny?> resolve(#A2): kotlin.js/Promise<#A2> // kotlin.js/Promise.Companion.resolve|resolve(0:0){0§<kotlin.js.JsAny?>}[0]
         final fun <#A2: kotlin.js/JsAny?> resolve(kotlin.js/Promise<#A2>): kotlin.js/Promise<#A2> // kotlin.js/Promise.Companion.resolve|resolve(kotlin.js.Promise<0:0>){0§<kotlin.js.JsAny?>}[0]
         final fun reject(kotlin.js/JsAny): kotlin.js/Promise<kotlin/Nothing> // kotlin.js/Promise.Companion.reject|reject(kotlin.js.JsAny){}[0]
+        final fun reject(kotlin.js/JsError): kotlin.js/Promise<kotlin/Nothing> // kotlin.js/Promise.Companion.reject|reject(kotlin.js.JsError){}[0]
     }
 }
 
@@ -15427,9 +15496,14 @@
 final class kotlin.js/JsBoolean : kotlin.js/JsAny // kotlin.js/JsBoolean|null[0]
 
 // Targets: [wasmJs]
+final class kotlin.js/JsError : kotlin.js/JsAny { // kotlin.js/JsError|null[0]
+    constructor <init>() // kotlin.js/JsError.<init>|<init>(){}[0]
+}
+
+// Targets: [wasmJs]
 final class kotlin.js/JsException : kotlin/Throwable { // kotlin.js/JsException|null[0]
     final val message // kotlin.js/JsException.message|{}message[0]
-        final fun <get-message>(): kotlin/String // kotlin.js/JsException.message.<get-message>|<get-message>(){}[0]
+        final fun <get-message>(): kotlin/String? // kotlin.js/JsException.message.<get-message>|<get-message>(){}[0]
     final val thrownValue // kotlin.js/JsException.thrownValue|{}thrownValue[0]
         final fun <get-thrownValue>(): kotlin.js/JsAny? // kotlin.js/JsException.thrownValue.<get-thrownValue>|<get-thrownValue>(){}[0]
 }
@@ -15441,6 +15515,14 @@
 final class kotlin.js/JsString : kotlin.js/JsAny // kotlin.js/JsString|null[0]
 
 // Targets: [wasmJs]
+final val kotlin.js/length // kotlin.js/length|@kotlin.js.JsArray<*>{}length[0]
+    final inline fun (kotlin.js/JsArray<*>).<get-length>(): kotlin/Int // kotlin.js/length.<get-length>|<get-length>@kotlin.js.JsArray<*>(){}[0]
+
+// Targets: [wasmJs]
+final val kotlin.js/thrownValue // kotlin.js/thrownValue|@kotlin.js.JsException{}thrownValue[0]
+    final fun (kotlin.js/JsException).<get-thrownValue>(): kotlin.js/JsAny? // kotlin.js/thrownValue.<get-thrownValue>|<get-thrownValue>@kotlin.js.JsException(){}[0]
+
+// Targets: [wasmJs]
 final fun (kotlin.js/JsAny).kotlin.js/toThrowableOrNull(): kotlin/Throwable? // kotlin.js/toThrowableOrNull|toThrowableOrNull@kotlin.js.JsAny(){}[0]
 
 // Targets: [wasmJs]
@@ -15498,6 +15580,9 @@
 final fun <#A: kotlin.js/JsAny?> (kotlin/Array<#A>).kotlin.js/toJsArray(): kotlin.js/JsArray<#A> // kotlin.js/toJsArray|toJsArray@kotlin.Array<0:0>(){0§<kotlin.js.JsAny?>}[0]
 
 // Targets: [wasmJs]
+final fun <#A: kotlin.js/JsAny?> kotlin.js/JsArray(): kotlin.js/JsArray<#A> // kotlin.js/JsArray|JsArray(){0§<kotlin.js.JsAny?>}[0]
+
+// Targets: [wasmJs]
 final fun <#A: kotlin/Any> (#A).kotlin.js/toJsReference(): kotlin.js/JsReference<#A> // kotlin.js/toJsReference|toJsReference@0:0(){0§<kotlin.Any>}[0]
 
 // Targets: [wasmJs]
diff --git a/native/native.tests/klib-ir-inliner/testFixtures/org/jetbrains/kotlin/konan/test/converters/NativeDeserializerFacade.kt b/native/native.tests/klib-ir-inliner/testFixtures/org/jetbrains/kotlin/konan/test/converters/NativeDeserializerFacade.kt
index 36a330d..096614e 100644
--- a/native/native.tests/klib-ir-inliner/testFixtures/org/jetbrains/kotlin/konan/test/converters/NativeDeserializerFacade.kt
+++ b/native/native.tests/klib-ir-inliner/testFixtures/org/jetbrains/kotlin/konan/test/converters/NativeDeserializerFacade.kt
@@ -146,7 +146,8 @@
                 // TODO KT-77493: Disable PL after all tests for invisible references would be migrated to diagnostic tests
                 partialLinkageConfig = PartialLinkageConfig(PartialLinkageMode.ENABLE, PartialLinkageLogLevel.ERROR),
                 builtIns = irBuiltIns,
-                messageCollector = messageCollector
+                messageCollector = messageCollector,
+                platform = moduleDescriptor.platform!!
             ),
             libraryBeingCached = null,
             userVisibleIrModulesSupport = UserVisibleIrModulesSupport(externalDependenciesLoader = UserVisibleIrModulesSupport.ExternalDependenciesLoader.EMPTY),