Embedding Rust code in Node.js App using Neon

What is Node?

Node is one of the most popular platforms which is used to develop web applications. It became a reality when the initial developers of JavaScript made it possible to run JavaScript as an autonomous application on our machines. This allowed JavaScript to do much more work than just making a website more interactive. Node gave JavaScript the ability to work similarly to other programming languages like Python. Node.js runs on the Chrome V8 engine. This engine takes the JavaScript code and converts it into a very fast functioning machine code. Machine code is something that the system or computer can run without having to interpret it first. Although it has features like asynchronous function execution and Non-blocking behavior it is not as fast as Rust or other languages like Go.?

What is Rust?

Rust is a strongly typed language. It is also a strongly compiled language. Rust is a language that is filled with exceptional features like anonymous functions, closure, a very rich standard library (STD), polymorphism, strong types, a tremendous build system, and a package manager amongst other great features. Rust is also considered a Memory Safe Language (MSL) because it checks the memory at the time of compilation. With all these great features of Rust, one thinks to him/herself that can I write JavaScript along with Rust? That is where Neon comes in. Neon allows its users to write JavaScript along with Rust. Neon provides the type safety and memory safety of Rust combined with JavaScript.

What is Neon?

Neon is a toolchain and a library created to embed RUST code into Node.js applications and libraries.  Neon endeavors to make Node modules more straightforwardly. Neon allows its users to write crash-free native modules as well as the type and memory-safe modules.

Nodejs has been a popular choice for developing enterprise-level applications. Given below are the benefits of Neon.

  • High Performance
  • Provides access to native OS-specific libraries
  • Provides access to Rust?s eco-system by the usage of Cargo
  • Allows for parallel programming
  • Usage of Threads

It also provides a CLI (Command Line Interface) and workflow bound with conventions that eradicate the trouble of building native modules of Node.

Setup of a basic Neon project

This example will display the short version of how powerful Neon is: Rust?s crate ecosystem is growing very quickly and is filled with tons of useful and distinctive libraries. It fills the gaps left in many low-level capabilities or high-performing data structures that can be very difficult to find in npm.

Making a new project:

First and foremost let?s make our new  cpu-count Neon project. What cpu-count does is that it returns how many processors are there in our system. First of all, let?s get all the dependencies needed to be installed into our system. We can do this using the following:

[dependencies.neon]features = [“napi-6”] 

Building a New Project:

We can use the following command to locate and build the project

cd CPU-countnpm install 

After the build process is done it will generate a few files. Now, let?s run the project!

node> require(‘.’).hello()hello node

Now lets add a rust dependency and implement our function:

[dependencies]num_cpus = “1”

use neon::prelude::*;

fn get_num_cpus(mut cx: FunctionContext) -> JsResult<JsNumber> {    Ok(cx.number(num_cpus::get() as f64))}

After this just rebuild your project and it should work fine!

npm run build — –release

This command will create a build for your project. Although builds usually take a little longer to compile.

Setup of a Module

After installation of Neon and the Rust toolchain, we can utilize neon new <project-name> to set up a skeleton Node module that inserts a Cargo.toml file and a Rust source file which also includes a demonstration of a hello function. We can implement any Rust dependency to Cargo.toml. You can also export a function to be later utilized in a Node program by the following steps:

The first step is to register the function using the following example of code:-

register_module!(mut m, {

m.export_function(“myFunc”, thread_count)

});

After that, export it from lib/index.js:

const addon = require(‘../native’);

module.exports = addon.myFunc;

After that when your code is ready to be used, you can build the Node module like this:

neon build ?release

Although it might seem easy one should always pay attention and try to be a good member of the Node environment. Any Rust function that we export should be of a specific type:

fn add1One(mut cx: FunctionContext) -> JsResult<JsNumber> {

    …

    }

Here the FunctionContext allows you to access the Node caller environment which includes its arguments list. Similarly, a function that is exported should return a JsResult, which is an option type that specifies the function returning a given type or throws a JavaScript exception. This is how you can access a specific argument:

let x = cx.argument::<JsNumber>(0)?.value();

In order to return a value that is coming from an exported function, one should cast it to its corresponding expected value. Meaning if your function returns a number, you would utilize the Rust as f64 when returning it:

Ok(cx.number(num_cpus::get() as f64))

One of the few advantages of building a native Neon module is that we have the possibility of executing asynchronous background tasks. Neon utilizes the N-API?s microtasks API to that aim and it depends on callbacks and promises on the JavaScript side to control the async task execution. Neon has been known to be utilized with other frameworks like Electron. Although right now the use of electron-build-env is used to build any Neon dependencies in Electron apps. Electron really has become the foremost technology in terms of creating cross-platform desktop applications. It is known to be used on very popular platforms like Atom, Spotify, Visual Studio Code, Discord, Slack, and many more. 

Conclusion:

In conclusion, Neon can be a very powerful tool to use when it comes to building web applications or other projects made with Node. Neon has very little memory footprint and is used to make your product lightning fast. With the power of Neon and the usefulness of Node one can efficiently create and maintain high-level projects. 

Author Bio:

Kapil Panchal ? Digital Marketing Manager

I am working as a Digital Marketing Manager in a reputed Node.js development company. Being a technical writing enthusiast and a goal-oriented individual with honed communication skills, I have served in the Information technology, Services, and Product industry. Having a high-energy level, I absolutely love what I do and I?m passionate about being better every day.

Discover more from Just Get Blogging

Subscribe now to keep reading and get access to the full archive.

Continue reading