Oxidation

Rust support has been required on all platforms since Firefox 54, and the first major Rust components were shipped in Firefox 56 (encoding_rs) and 57 (Stylo). Moving forward, the goal of Oxidation is to make it easier and more pleasant to use Rust in Firefox, and correspondingly to increase the amount of Rust code in Firefox.

This page is intended to serve as the starting point for all matters relating to Rust code in Firefox: the what, the why, and the how.

Guidelines

The goal of this section is to provide some high-level guidelines about when Rust should be used.

In summary, Rust should be used in the following situations.

For new components and completely rewritten components there should be a strong bias towards using Rust, especially for code around Firefox but not within Firefox.

For existing components it's more complicated!

The following sections have more detail. Ultimately, choice of language for a code component is an engineering decision, with corresponding trade-offs, and is best decided by individual teams.

Rust Strengths

Rust has the following strengths.

Memory safety, which prevents crashes and security vulnerabilities.

Thread safety, which enables improved performance via parallelism.

Nimbleness: the safety makes it easy to make significant changes quickly and with confidence.

Pleasant to use, particularly once a moderate level of experience has been reached.

A great community.

Rust Weaknesses

One major issue with Rust relates to personnel. There is a wide variety of experience levels within Mozilla, for both coding and reviewing. Also, Rust's learning curve is steep at the start, which can be intimidating.

There are also technical challenges.

Compile times are currently very slow and compilation uses too much memory.

Crossing the C++/Rust boundary layer can be difficult, and is relatively slow due to no inlining.

Bindgen can be tricky, especially working around clang bugs in different versions and on different platforms

rillian: "As I understand it, the problem is no one has set up tests on a cloud service, so there's no way for upstream to gate work on Android regressions. Qemu emulation is too slow. There aren't many services with arm support, but there are a couple of new options. If someone does the work of setting something up we should be able to get the Rust team to adopt it."

Integration with Gecko often requires adding wrapper/glue code. Such code is typically valuable and reusable, however.

Sharing components between Gecko and Servo is difficult.

The workflow is annoying and inefficient. Furthermore, permission to land directly on autoland is sometimes needed to fix problems, but few people have that.

vcs-sync/Phabricator/Lando will hopefully fix this.

There are continuous integration mismatches.

Servo CI is potentially under-resourced.

This is not relevant for Gecko-only Rust components, however.

Recommendations

Therefore, Rust is most suitable in the following situations.

For components that are relatively standalone, with small and simple APIs.

In terms of where to keep Rust crates, there are three options, from most-coupled to least-coupled.

Put the crate in mozilla-central or in Servo's repository.

For binding code, the decision to put it into Gecko or Servo can be difficult. The best choice depend on the details of the binding code in question.

Put the crate somewhere else (e.g. a separate GitHub repository), and regularly vendor it into mozilla-central.

This works well if relatively few people are working on the crate, and the API isn't too complex.

Can be useful if useful development can be done using just that crate, without the rest of Gecko or Servo.

This also makes sense for pre-existing third-party crates that we choose to import.

This is done by WebRender, for example.

Put the crate somewhere else (e.g. crates.io), and use Cargo to access it at build-time.

This is only suitable for highly general-purpose crates.

In general, erring on the side of tighter coupling is advisable. For example, the heapsize crate used in memory reporting was moved to crates.io, and then other crates came to depend on it. Later on it needed major API changes, and we ended up replacing it with a new crate called malloc_size_of (stored in Servo's repository) because that was easier than modifying heapsize.

Rust in Firefox

The #servo IRC channel contains lots of people who know about both Rust and Gecko.

Are you new to Rust and not sure if your Rust code could be improved? The following people can review Rust patches for Firefox from an "is this good Rust code?" point of view.

Alexis Beingessner (:gankro)

Josh Bowman-Matthews (:jdm)

Emilio Cobos Alvarez (:emilio)

Manish Goregaokar (:manishearth)

Nika Layzell (:mystor)

Cameron McCormack (:heycam)

Supported Rust versions for Firefox builds

Below are our expectations if everything goes smoothly; we may need newer toolchains to address specific issues. Our ultimate policy is just that release Firefox will not require unstable or beta Rust to build.