diff --git a/_config.yml b/_config.yml
index 0c2e717..8456fea 100644
--- a/_config.yml
+++ b/_config.yml
@@ -64,7 +64,7 @@ colors: #in hex code if not noted else
### VERSIONS ###
versions:
- scalaJS: 1.18.2
+ scalaJS: 1.19.0
scalaJSBinary: 1
scalaJS06x: 0.6.33
scalaJS06xBinary: 0.6
diff --git a/_data/library/versions.yml b/_data/library/versions.yml
index 479e576..a35e67f 100644
--- a/_data/library/versions.yml
+++ b/_data/library/versions.yml
@@ -35,3 +35,4 @@
- 1.16.0
- 1.17.0
- 1.18.0
+- 1.19.0
diff --git a/_posts/news/2025-04-21-announcing-scalajs-1.19.0.md b/_posts/news/2025-04-21-announcing-scalajs-1.19.0.md
new file mode 100644
index 0000000..e7eb360
--- /dev/null
+++ b/_posts/news/2025-04-21-announcing-scalajs-1.19.0.md
@@ -0,0 +1,192 @@
+---
+layout: post
+title: Announcing Scala.js 1.19.0
+category: news
+tags: [releases]
+permalink: /news/2025/04/21/announcing-scalajs-1.19.0/
+---
+
+
+We are pleased to announce the release of Scala.js 1.19.0!
+
+This release comes with significant performance improvements to the WebAssembly backend.
+For codebase where performance is dominated by computations (rather than JS interop), you can now expect the Wasm output to be faster than the JS output.
+
+Moreover, as of this writing, the latest versions of Firefox (since v131) and Safari (since v18.4) support all the WebAssembly features required to run Scala.js-on-Wasm.
+Chrome still requires a flag to enable exception handling.
+
+If you haven't tried the WebAssembly target yet, now is a good time to do so!
+
+Other highlights:
+
+* Native support for JavaScript `async/await`, through `js.async { ... }` and `js.await(...)`.
+* Small code size improvements for the JavaScript target when using SAM lambdas.
+* For Wasm only: support for the JavaScript Promise Integration feature (JSPI).
+
+Read on for more details.
+
+
+
+## Getting started
+
+If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/).
+
+If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js).
+
+Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues).
+
+## Release notes
+
+If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes.
+
+This is a **minor** release:
+
+* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.18.x can be used with 1.19.0 without change.
+* It is *not* forward binary compatible with 1.18.x: libraries compiled with 1.19.0 cannot be used with 1.18.x or earlier.
+* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.18.x (in particular in the presence of `-Xfatal-warnings`).
+
+As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first.
+
+## Enhancements with compatibility concerns
+
+### Drop support for non-strict floats
+
+Support for non-strict `Float`s was deprecated 3 years ago in Scala.js 1.9.0.
+We now removed that support.
+Builds configured to use non-strict floats (with `withStrictFloats(false)`) will refuse to compile.
+If that setting is used through an indirect dependency, it will be silently ignored.
+
+Strict floats are almost entirely backward compatible with non-strict floats.
+In general, strict floats mandate behavior which non-strict floats leave unspecified (so non-strict floats were always permitted to behave like strict floats).
+The only exception is that tests of the form `x.isInstanceOf[Float]` (or `case x: Float =>`) will answer `false` for number values that cannot exactly be represented in a 32-bit `Float`.
+
+We are not aware of any codebase that was ever adversely affected by strict float semantics.
+
+### Deprecate support for targeting ECMAScript 5.1
+
+The support for targeting ECMAScript 5.1 is currently the biggest source of alternative code paths and polyfills in our codebase.
+Moreover, the ES 5.1 output does not even have exactly the same semantics as later versions:
+
+* JS classes are not true classes. Notably, that means they cannot extend native ES classes, and they do not inherit static members.
+* Top-level exports are declared as vars instead of lets.
+
+10 years after the introduction of ECMAScript 2015, we believe it is time to deprecate the support for targeting ES 5.1, so that we can eventually remove it.
+The removal will happen in a future major or minor release of Scala.js.
+
+### Changes to the IR and linker APIs
+
+For tooling authors who directly manipulate the IR and linker APIs, there have been some breaking changes in that area.
+This is in line with our version policy for the linker APIs.
+
+The most likely changes you may hit are:
+
+* The `ir.Trees.Closure` node has two additional fields: `flags` and `resultType`.
+* All the "well-known" names that were previously in `ir.Names` have been moved to a new object `ir.WellKnownNames`.
+* `ir.Types.PrimRef` is not a case class anymore.
+
+## Enhancements
+
+### Native support for JS `async/await`
+
+Note 1: Scala 3 users will have to wait for a future release of Scala 3---likely 3.8.0---to be able to use this new feature.
+
+Note 2: when targeting WebAssembly, this feature requires support for JSPI (JavaScript Promise Integration).
+You can [check support for JSPI in various browsers here](https://webassembly.org/features/#table-row-jspi).
+On Node.js v23+, this requires the flag `--experimental-wasm-jspi`.
+
+This release adds a pair of primitives, `js.async` and `js.await`, which correspond to the `async/await` feature of JavaScript.
+In order to use these functions, you must configure Scala.js to target ECMAScript 2017 or later.
+In an sbt build, use the following setting:
+
+{% highlight scala %}
+// Target ES 2017 to enable async/await
+scalaJSLinkerConfig := {
+ scalaJSLinkerConfig.value
+ .withESFeatures(_.withESVersion(ESVersion.ES2017)) // enable async/await
+},
+{% endhighlight %}
+
+You can then use `js.async { ... }` blocks containing `js.await` calls.
+For example:
+
+{% highlight scala %}
+val p: js.Promise[String] = downloadSomething()
+val result: js.Promise[Int] = js.async {
+ val text: String = js.await(p)
+ text.toInt
+}
+{% endhighlight %}
+
+`js.async { ... }` executes a block of code under a JavaScript `async` context.
+The block of code can await `js.Promise`s using `js.await`.
+Doing so will continue the execution after the call to `js.await` when the given `Promise` is resolved.
+If the `Promise` is rejected, the exception gets rethrown at the call site.
+
+A block such as `js.async { body }` is equivalent to an immediately-applied JavaScript `async` function:
+
+{% highlight javascript %}
+(async () => body)()
+{% endhighlight %}
+
+`js.async` returns a `js.Promise` that will be resolved with the result of the code block.
+If the block throws an exception, the `Promise` will be rejected.
+
+Calls to `js.await` can only appear within a `js.async` block.
+They must not be nested in any local method, class, by-name argument or closure.
+The latter includes `for` comprehensions.
+They may appear within conditional branches, `while` loops and `try/catch/finally` blocks.
+
+### Orphan `await`s in WebAssembly
+
+When compiling for Scala.js-on-Wasm only, you can allow calls to `js.await` anywhere, by adding the following import:
+
+{% highlight scala %}
+import scala.scalajs.js.wasm.JSPI.allowOrphanJSAwait
+{% endhighlight %}
+
+Calls to orphan `js.await`s are validated at run-time.
+There must exist a dynamically enclosing `js.async { ... }` block on the call stack.
+Moreover, there cannot be any JavaScript frame (JavaScript function invocation) in the call stack between the `js.async { ... }` block and the call to `js.await`.
+If those conditions are not met, a JavaScript exception of type `WebAssembly.SuspendError` gets thrown.
+
+The ability to detach `js.await` calls from their corresponding `js.async` block is a new superpower offered by JSPI.
+It means that, as long as you enter into a `js.async` block somewhere, you can *synchronously await* `Promise`s in any arbitrary function!
+This is a power of the same sort as Loom on the JVM.
+We are looking forward to seeing new libraries built on these primitives to offer efficient and straightforward APIs.
+
+### Performance improvements for WebAssembly
+
+Scala.js 1.19.0 brings significant performance improvements to the WebAssembly output.
+Starting with this release, the WebAssembly output is faster than the JavaScript output on our benchmarks (geomean of the running time is 15% lower).
+
+Note that our benchmarks do not measure JavaScript interop in any significant way.
+If your application's performance depends mostly on JS interop, the JavaScript output is probably still faster (and will remain so for the foreseeable future).
+However, if your bottleneck is in computations inside Scala code, compiling to WebAssembly should now give you a free performance boost.
+
+The WebAssembly target also received additional improvements in terms of code size and run-time memory consumption.
+
+As a reminder, you may read detailed information about [the WebAssembly backend in the docs]({{ BASE_PATH }}/doc/project/webassembly.html).
+
+## Miscellaneous
+
+### New JDK APIs
+
+This release adds support for the following JDK methods:
+
+* Most of `java.util.random.RandomGenerator`
+
+### Improvements to the JUnit interface
+
+Thanks to [`@dubinsky`](https://github.com/dubinsky) for contributing two improvements to the integration of our JUnit implementation with external tooling (in particular Gradle):
+
+* populate `sbt.testing.Event.throwable` on test failure, and
+* populate `sbt.testing.Event.duration`.
+
+## Bug fixes
+
+The following bugs have been fixed in 1.19.0:
+
+* [#5131](https://github.com/scala-js/scala-js/issues/5131) Linker not noticing instance test changes
+* [#5135](https://github.com/scala-js/scala-js/issues/5135) Deadlock in concurrent initialization of `ir.Names` and `ir.Types`.
+
+You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.19.0+is%3Aclosed).
diff --git a/assets/badges/scalajs-1.19.0.svg b/assets/badges/scalajs-1.19.0.svg
new file mode 100644
index 0000000..a95b45f
--- /dev/null
+++ b/assets/badges/scalajs-1.19.0.svg
@@ -0,0 +1 @@
+
diff --git a/doc/all-api.md b/doc/all-api.md
index f9fe4b0..867315b 100644
--- a/doc/all-api.md
+++ b/doc/all-api.md
@@ -5,6 +5,16 @@ title: All previous versions of the Scala.js API
## All previous versions of the API
+### Scala.js 1.19.0
+* [1.19.0 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.19.0/scala/scalajs/js/index.html)
+* [1.19.0 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.19.0/)
+* [1.19.0 scalajs-javalib-intf]({{ site.production_url }}/api/scalajs-javalib-intf/1.19.0/)
+* [1.19.0 scalajs-ir]({{ site.production_url }}/api/scalajs-ir/1.19.0/org/scalajs/ir/index.html)
+* [1.19.0 scalajs-linker-interface]({{ site.production_url }}/api/scalajs-linker-interface/1.19.0/org/scalajs/linker/interface/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-interface-js/1.19.0/org/scalajs/linker/interface/index.html))
+* [1.19.0 scalajs-linker]({{ site.production_url }}/api/scalajs-linker/1.19.0/org/scalajs/linker/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-js/1.19.0/org/scalajs/linker/index.html))
+* [1.19.0 scalajs-test-adapter]({{ site.production_url }}/api/scalajs-sbt-test-adapter/1.19.0/org/scalajs/testing/adapter/index.html)
+* [1.19.0 sbt-scalajs]({{ site.production_url }}/api/sbt-scalajs/1.19.0/#org.scalajs.sbtplugin.package)
+
### Scala.js 1.18.2
* [1.18.2 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.18.2/scala/scalajs/js/index.html)
* [1.18.2 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.18.2/)
diff --git a/doc/internals/version-history.md b/doc/internals/version-history.md
index 03204ca..1e0fb62 100644
--- a/doc/internals/version-history.md
+++ b/doc/internals/version-history.md
@@ -5,6 +5,7 @@ title: Version history
## Version history of Scala.js
+- [1.19.0](/news/2025/04/21/announcing-scalajs-1.19.0/)
- [1.18.2](/news/2025/01/23/announcing-scalajs-1.18.2/)
- [1.18.1](/news/2025/01/09/announcing-scalajs-1.18.1/)
- ~~1.18.0~~ ([severely broken](https://github.com/scala-js/scala-js/issues/5107) and therefore never announced)
diff --git a/doc/project/webassembly.md b/doc/project/webassembly.md
index 84161e2..49a3ebe 100644
--- a/doc/project/webassembly.md
+++ b/doc/project/webassembly.md
@@ -31,9 +31,9 @@ The Wasm backend emits code with the following requirements:
* Wasm GC
* Exception handling, including the latest `exnref`-based variant
* The `ESModule` module kind (see [emitting modules](./module.html))
-* Strict floats (which is the default since Scala.js 1.9.0; non-strict floats are deprecated)
-Supported engines include Node.js 22, Chrome and Firefox, all using some experimental flags (see below).
+Supported engines include Node.js 23, Chrome, Firefox and Safari.
+Node.js and Chrome currently require using some experimental flags (see below).
## Language semantics
@@ -75,7 +75,8 @@ scalaJSLinkerConfig := {
jsEnv := {
val config = NodeJSEnv.Config()
.withArgs(List(
- "--experimental-wasm-exnref", // required
+ "--experimental-wasm-exnref", // always required
+ "--experimental-wasm-jspi", // required for js.async/js.await
"--experimental-wasm-imported-strings", // optional (good for performance)
"--turboshaft-wasm", // optional, but significantly increases stability
))
@@ -90,11 +91,12 @@ The backend emits ES modules with the same layout and interface as those produce
Here are some engines known to support enough Wasm features.
-### Node.js 22
+### Node.js 23
As mentioned above, Node.js 23 and above requires the following flags:
-* `--experimental-wasm-exnref`: required
+* `--experimental-wasm-exnref`: always required
+* `--experimental-wasm-jspi`: required to use `js.async`/`js.await`
* `--experimental-wasm-imported-strings`: optional (good for performance)
* `--turboshaft-wasm`: optional, bug significantly increases stability
@@ -102,17 +104,26 @@ As mentioned above, Node.js 23 and above requires the following flags:
In `chrome://flags/`, enable ["Experimental WebAssembly"](chrome://flags/#enable-experimental-webassembly-features).
+For `js.async`/`js.await` support, also enable ["Experimental WebAssembly JavaScript Promise Integration (JSPI)"](chrome://flags/#enable-experimental-webassembly-jspi).
+
### Firefox
-In `about:config`, enable `javascript.options.wasm_exnref`.
+Firefox supports all the "always required" features since v131, with enhanced performance since v134.
+
+For `js.async/js.await` support, go to `about:config`, enable `javascript.options.wasm_js_promise_integration`.
+This may require a Firefox Nightly build when you read these lines, although it should be available by default soon.
+
+### Safari
-Make sure to *disable* `javascript.options.wasm_js_string_builtins`.
-Firefox has two issues with it that break Scala.js ([1919901](https://bugzilla.mozilla.org/show_bug.cgi?id=1919901) and [1920337](https://bugzilla.mozilla.org/show_bug.cgi?id=1920337)).
+Safari supports all the "always required" features since v18.4.
+
+`js.async/js.await` is not supported yet, however.
## Performance
-Performance of the generated code is currently a hit-or-miss.
-Depending on the codebase, it may be several times faster or slower than the JS backend.
+If the performance of your application depends a lot on JavaScript interop, the Wasm output may be (significantly) slower than the JS output.
+
+For applications whose performance is dominated by computions inside Scala code, the Wasm output should be significantly faster than the JS output (geomean 15% lower run time across our benchmarks).
Further work on improving performance is ongoing.
Keep in mind that performance work on the Wasm backend is a few months old, compared to a decade of optimizations in the JS backend.
diff --git a/doc/semantics.md b/doc/semantics.md
index 11d7cb2..bd75c43 100644
--- a/doc/semantics.md
+++ b/doc/semantics.md
@@ -89,25 +89,6 @@ Instead, it uses the more sensible `java.lang.Void`, as `Void` is the boxed clas
This means that while `java.lang.Void` is not instantiable on the JVM, in Scala.js it has a singleton instance, namely `()`.
This also manifests itself in `Array[Unit]` which is effectively `Array[java.lang.Void]` at run-time, instead of `Array[scala.runtime.BoxedUnit]`.
-### Non-strict floats (deprecated; default until Scala.js 1.8.0)
-
-Until v1.8.0, Scala.js underspecified the behavior of `Float`s by default with so-called *non-strict floats*.
-
-Non-strict floats can still be enabled with the following sbt setting:
-
-{% highlight scala %}
-scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(false)) }
-{% endhighlight %}
-
-Under non-strict floats, any `Float` value can be stored as a `Double` instead, and any operation on `Float`s can be computed with double precision.
-The choice of whether or not to behave as such, when and where, is left to the implementation.
-In addition, `x.isInstanceOf[Float]` will return `true` for any `number` values (not only the ones that fit in a 32-bit float).
-
-Non-strict floats are deprecated and will eventually be removed in a later major or minor version of Scala.js.
-
-Enabling non-strict floats may significantly improve the performance (up to 4x for `Float`-intensive applications) when targeting JS engines that do not support [the `Math.fround` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround), such as Internet Explorer (which implies emitting ES 5.1 code).
-If you are in that situation, we advise to use `Double`s instead of `Float`s as much as possible.
-
## Undefined behaviors
The JVM is a very well specified environment, which even specifies how some
@@ -238,3 +219,24 @@ val = Value(
We believe that this covers most use cases of
`scala.Enumeration`. Please let us know if another (generalized)
rewrite would make your life easier.
+
+## Historical
+
+### Non-strict floats (removed in Scala.js 1.19.0; default until 1.8.0)
+
+Until v1.8.0, Scala.js underspecified the behavior of `Float`s by default with so-called *non-strict floats*.
+
+Non-strict floats could be enabled with the following sbt setting, until v1.19.0 excluded:
+
+{% highlight scala %}
+scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(false)) }
+{% endhighlight %}
+
+Under non-strict floats, any `Float` value can be stored as a `Double` instead, and any operation on `Float`s can be computed with double precision.
+The choice of whether or not to behave as such, when and where, is left to the implementation.
+In addition, `x.isInstanceOf[Float]` will return `true` for any `number` values (not only the ones that fit in a 32-bit float).
+
+Non-strict floats were deprecated in v1.8.0 and removed in v1.19.0.
+
+Non-strict floats could significantly improve the performance (up to 4x for `Float`-intensive applications) when targeting JS engines that do not support [the `Math.fround` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround), such as Internet Explorer (which implies emitting ES 5.1 code).
+If you are in that situation, we advise to use `Double`s instead of `Float`s as much as possible.