Boa release v0.19
Summary
Boa v0.19 is now available! After 4 months of development we are very happy to present you the latest release of the Boa JavaScript engine. Boa makes it easy to embed a JS engine in your projects, and you can even use it from WebAssembly. See the about page for more info.
In this release, our conformance has grown from 85.03% to 87.3% in the official ECMAScript Test Suite (Test262). Interestingly, this was partly because around 2000 tests were removed from test262 as part of the removal of custom calendars and timezones. Overall, Boa's conformance in real terms has improved by ~6%.
You can check the full list of changes here, and the full information on conformance here.
Highlights
Temporal
Boa is continuing to progress on Temporal. The Temporal API is a new
set of built-in objects and functions that is designed to be a more modern replacement for the Date
object, providing a more feature-rich and flexible API for working with dates and times.
It is currently a stage 3 proposal and we are working alongside the TC39 champions to put together a solid Rust implementation. Since Temporal is such an extensive specification, we have done most of the work outside of Boa so that it can be used in other projects. This work can be found in the temporal_rs repository.
We hope to release a full blog post on Temporal in the future, but for now you can see the previous release notes for some examples on how to use it. You can also look at the Temporal Cook Book for some examples too!
If you're interested in learning more or want to contribute to the native Rust implementation of
Temporal, feel free to check out temporal_rs
's issues!
Boa's conformance on the Temporal test suite has grown from 19.35% to 24.61% in this release.
New Benchmark Suite, Faster CI and reduced repo size
Boa has had an overhaul of its older criterion benchmark suite to a new end to end benchmark suite. We had finally outgrown the old benchmark suite and needed a new one that could handle the new features and improvements we were making to the engine. The former benchmark suite has been there almost since the beginning, and was created as a way to keep an eye on certain functions and routines within Boa itself. Although useful, it wasn't comparable to other engines due to being so specific on how Boa works.
The new suite is taken from V8's old benchmark suite which, despite being deprecated, is still for comparative performance. Over time we will eventually need to work with other engines to have a more advanced benchmarking suite which can take into account modern JavaScript, but for now this is a good start.
This change also offered a nice side effect of not having benchmark or test262 data in the main repository anymore. Last time we released we had reports of the repository being too large, so we've taken steps to reduce the size of the repository by moving this data to a separate repository and building a nightly version for reporting. Not only this makes it easier for anyone cloning Boa today but pushes to main
are now much faster due to us not having to run test262 or Benchmarks each time.
Migration to Matrix
The Boa team will be migrating to Matrix from our Discord servers over the course of this year. This means we will hang out in the #boa:matrix.org
room and will be available for questions and discussions there. We will also be using Matrix for other break-out rooms on future development in areas such as Performance, Intl and Temporal. We will be keeping the Discord server open for a while to allow people to migrate over, but we will eventually close it down sometime in 2025.
Boa has long been a user of Discord, pretty much since the beginning of the project, but as the project has grown and matured, we have chosen to move more in line to other communities who use Matrix for communication, such as TC39 who work on ECMAScript standard. With Boa's increased conformance and ability to work closer with the standard committee when implementing Temporal and other new specifications meant that a migration to Matrix was the most natural choice to ease communication with the broader JavaScript implementer communities.
Optimizations
Release binary stripping
Boa's binaries are on the larger side by default due to including ICU data. We may eventually move to a system where this needs to be fed from the host. However, until then there are other tricks we can employ to bring down our size, one of those is binary stripping. We can remove debug information from the release binary to reduce the size.
crate | v0.18 | v0.19 |
---|---|---|
boa | 26MB | 25MB |
boa_tester | 27MB | 25MB |
Dense array storage variants for i32 and f64
This release adds dense array storage variants for i32
and f64
types. This allows us to store arrays of these types more efficiently, and also allows us to optimize certain operations on these arrays.
If you want to inspect the storage type of an array in Boa you can use the $boa.object.indexedStorageType()
APi. Here are some examples:
let a = [1, 2];
$boa.object.indexedStorageType(a); // 'DenseI32'
a.push(0xdeadbeef);
$boa.object.indexedStorageType(a); // 'DenseI32'
a.push(0.5);
$boa.object.indexedStorageType(a); // 'DenseF64'
a.push("Hello");
$boa.object.indexedStorageType(a); // 'DenseElement'
a[100] = 100; // Make a hole
$boa.object.indexedStorageType(a); // 'SparseElement'
Much of this work is possible thanks to our implementation of Object Shapes
New Contributors
Thank you to the new contributors to Boa for this release, you can find their contributions below:
- @robot-head made their first contribution in https://github.com/boa-dev/boa/pull/3730
- @hansl made their first contribution in https://github.com/boa-dev/boa/pull/3755
- @NickTomlin made their first contribution in https://github.com/boa-dev/boa/pull/3793
- @linusg made their first contribution in https://github.com/boa-dev/boa/pull/3800
- @getong made their first contribution in https://github.com/boa-dev/boa/pull/3836
- @leoflalv made their first contribution in https://github.com/boa-dev/boa/pull/3867
- @CrazyboyQCD made their first contribution in https://github.com/boa-dev/boa/pull/3898
Looking Forward
API ergonomics
Before finishing this blog post, we wanted to give a special shoutout to @hansl, one of our new contributors for this release! He's been working on improving the ergonomics around exposing Rust functions and types as ECMAScript functions and classes with a lot of nice API enhancements. Some notable PRs are:
- Add a boa_interop crate
- Add a new type Convert<> to convert values
- Add a ContextData struct to inject host defined types from the context
- Add a js_class to implement the Class trait without boilerplate
Unfortunately, the aforementioned boa_interop
crate was not published for this version, and that's
because we would like to polish it first and integrate it within the other crates of the project.
However, we can give you a sneak peek of what some of the new APIs will allow you to do. Hopefully
this will make you look forward for v0.20!
use boa_interop::{js_class, Ignore, JsClass};
#[derive(Clone, Trace, Finalize, JsData)]
pub enum Animal {
Cat,
Dog,
Other,
}
js_class! {
// Implements the [`Class`] trait for the `Animal` enum.
class Animal {
// This sets a field on the JavaScript object. The arguments to
// `init` are the arguments passed to the constructor.
public age(_name: Ignore, age: i32) -> i32 {
age
}
// This is called when a new instance of the class is created in
// JavaScript, e.g. `new Animal("cat")`.
constructor(name: String) {
match name.as_str() {
"cat" => Ok(Animal::Cat),
"dog" => Ok(Animal::Dog),
_ => Ok(Animal::Other),
}
}
// Declare a function on the class itself.
fn speak(this: JsClass<Animal>) -> JsString {
match *this.borrow() {
Animal::Cat => js_string!("meow"),
Animal::Dog => js_string!("woof"),
Animal::Other => js_string!(r"¯\_(ツ)_/¯"),
}
}
}
}
Performance
Now that our conformance is farily high (87.3% in Test262), we will be focusing on improving the performance of the engine. This will involve re-writing the Garbage Collector from the one we have now which was a fork of rust-gc and modified heavily, to something which will work better for the engine and allow us to have paritioning, snapshots and other features which are not possible with the current GC. If this interests you, you can join the effort in our Matrix GC chat (see Migration To Matrix above).
Boa will also be working on migrating from a stack VM to a register-based VM. This will allow us to optimize the engine further and make it more competitive with other engines. We will also be working on improving the performance of the engine in general, and we will be looking at ways to make the engine faster and more efficient.
v1.0
We hope that the changes mentioned above will bring us closer to a v1.0 release. We are still some way off, but we are making progress and we are confident that we will be able to release a v1.0 version of Boa in the future.
How can you support Boa?
Boa is an independent JavaScript engine implementing the ECMAScript specification, and we rely on the support of the community to keep it going. If you want to support us, you can do so by donating to our open collective. Proceeeds here go towards this very website, the domain name, and remunerating members of the team who have worked on the features released.
If financial contribution is not your strength, you can contribute by asking to be assigned to one of our open issues, and asking for mentoring if you don't know your way around the engine. Our contribution guide should help you here. If you are more used to working with JavaScript or frontend web development, we also welcome help to improve our web presence, either in our website, or in our testing representation page or benchmarks page. You can also contribute to our Criterion benchmark comparison GitHub action.
We are also looking to improve the documentation of the engine, both for developers of the engine itself and for users of the engine. Feel free to contact us in Matrix.
Thank You
Once again, big thanks to all the contributors of this release!!