70 %
Chris Biscardi

Rust for JS

We are heading toward more and more JS tooling being built in Rust. While it is still early, I believe that there are already signs of this becoming a dominant approach over the next few years. This is a list of interesting technology being built on that path, both higher level projects and lower level tools.

orogene

A next-generation platform and package manager for Node.js-compatible and frontend JavaScript projects!

Probably the most ambitious Rust-for-JS project around currently.

Notably orogene has completely embedded node in a crate they call obelisk. This is pretty major in terms of current runtimes, as node is the most popular and allows orogene to ship a single binary rather than an npm package.

RSLint

RSLint is an ESLint replacement

dprint

dprint is a prettier replacement

Volta

Volta is like nvm, but in Rust, which means we get something closer to rust-toolchain.toml for node.

  • Volta manages npm/yarn versions as well as node versions
  • You can pin a globally installed npm package binary to a specific node.js engine as well as use different "globally installed binaries" when in different projects/directories.

SWC

SWC is similar to babel, but written in Rust. It is most often advertised as an npm package and allows you to write the equivalent of babel plugins in JS as shown here. It is exposed to node projects through napi-rs.

swc-strip-console-plugin.js
javascript
import { CallExpression, Expression } from "@swc/core";
import Visitor from "@swc/core/Visitor";
class ConsoleStripper extends Visitor {
visitCallExpression(e: CallExpression): Expression {
if (e.callee.type !== "MemberExpression") {
return e;
}
if (
e.callee.object.type === "Identifier" &&
e.callee.object.value === "console"
) {
if (e.callee.property.type === "Identifier") {
return {
type: "UnaryExpression",
span: e.span,
operator: "void",
argument: {
type: "NumericLiteral",
span: e.span,
value: 0
}
};
}
}
return e;
}
}
const out = transformSync(
`
if (foo) {
console.log("Foo")
} else {
console.log("Bar")
}`,
{
plugin: m => new ConsoleStripper().visitProgram(m)
}
);
out.code ===
`if (foo) {
void 0;
} else {
void 0;
}`;

The SWC project also includes spack, which is a bundler most often thought of as in the "Webpack" class of libs. Spack is still early.

SWC's crates can be used as a Rust library if you commit to using Rust nightly and installing from GitHub, which is what Toast does. The SWC git repo is set up as a cargo workspace.

It is currently used by Deno and Framer in production.

Toast

Toast builds on top of SWC and other Rust crates to offer a Next or Gatsby-like experience to UI developers. It calls out to node via domain sockets rather than NAPI for node-related behaviors. Over time it intends to fit more and more of the functionality into the Rust binary while also providing a typical JavaScript experience to users.

Alternative Runtimes

More

People are increasingly looking to build JS tooling in Rust, such as Joel Denning's rawsemble, Fábio Santos' work on Terser, Relay's work on Neon and WASM variations of the Relay compiler. There are some n-api binding based libraries at napi-rs/node-rs for things like bcrypt.