Getting started
High-performance Rust functions in Node.js
Last updated
Was this helpful?
High-performance Rust functions in Node.js
Last updated
Was this helpful?
There are great use cases for , especially for AI, blockchain, and big data applications. In this tutorial, I will show you how to incorporate WebAssembly functions, written in Rust, into Node.js applications on the server. This approach combines Rust's performance, WebAssembly's security and portability, and JavaScript's ease-of-use. A typical Rust + Node.js hybrid app works like this.
The host application is a Node.js web application written in JavaScript. It makes WebAssembly function calls.
The WebAssembly bytecode program is written in Rust. It runs inside the SSVM, and is called from the Node.js web application.
The source code of the tutorial is . If you just want to try it out, you can and .
Since we are building Rust functions to run in Node.js, make sure that you have and installed on your computer.
We use the Second State Virtual Machine (SSVM) , an open source WebAssembly runtime , together with Node.js.
The and npm modules install the into Node.js as a native addon, and provides the necessary compiler tools. about the tool.
Next, you can compile the Rust source code into WebAssembly bytecode and generate the accompanying JavaScript module for the Node.js host environment.
The result are files in the pkg/
directory. the .wasm
file is the WebAssembly bytecode program, and the .js
files are for the JavaScript module.
Start the Node.js application server as follows.
Then, you can test it.
Besides passing string values between Rust and JavaScript, the ssvmup tool supports the following data types.
Rust call parameters can be any combo of i32
, String
, &str
, Vec<u8>
, and &[u8]
Return value can be i32
or String
or Vec<u8>
For complex data types, such as structs, you could use JSON strings to pass data.
Perhaps the most interesting is the create_line()
function. It takes two JSON strings, each representing a Point
struct, and returns a JSON string representing a Line
struct. Notice that both the Point
and Line
structs are annotated with Serialize
and Deserialize
so that the Rust compiler automatically generates necessary code to support their conversion to and from JSON strings.
After running ssvmup to build the Rust library, running app.js
in Node.js environment produces the following output.
In this example, our Rust program appends the input string after “hello”. Below is the content of the Rust program . You can define multiple external functions in this library file, and all of them will be available to the host JavaScript app via WebAssembly. Just remember to annotate each function with #[wasm_bindgen]
so that knows to generate the correct JavaScript to Rust interface for it when you build it.
Next, go to the node
folder and examine the JavaScript program . With the generated hello_lib.js
module, it is very easy to write JavaScript to call WebAssembly functions. Below is the node application app.js
. It simply imports the say()
function from the generated module. The node application takes the name
parameter from incoming an HTTP GET request, and responds with “hello name
”.
With JSON support, you can .
The Rust program in the demonstrates how to pass in call arguments in various supported types, and return values.
Next, let's examine the JavaScript program . It shows how to call the Rust functions. As you can see String
and &str
are simply strings in JavaScript, i32
are numbers, and Vec<u8>
or &[8]
are JavaScript Uint8Array
. JavaScript objects need to go through JSON.stringify()
or JSON.parse()
before being passed into or returned from Rust functions.
Now we have seen a very simple example to call a Rust function from JavaScript in a Node.js application. we will discuss how to pass arbitrary arguments from a JavaScript program to Rust.