w3resource

How to use Rust with NPM for Native Modules and WASM?


Rust and NPM Integration: A Comprehensive Guide

While Rust and Node.js (NPM) originate from different ecosystems, they can seamlessly integrate to build high-performance applications. Rust offers robust features for computational tasks, while NPM provides access to a vast repository of JavaScript libraries. Integrating Rust with NPM allows developers to create fast, efficient, and scalable Node.js modules or combine Rust’s capabilities with the JavaScript ecosystem.

This guide demonstrates how Rust can be used alongside NPM, including the use of tools like wasm-pack for WebAssembly and neon for native modules.


Integrating Rust with NPM

There are two main ways to connect Rust with NPM:

    1. Building Native Node.js Modules: Using Rust to create modules directly callable from JavaScript.

    2. Compiling to WebAssembly (WASM): Using Rust to write WebAssembly modules for frontend or backend use.


Syntax for Native Modules using Neon

Here's how you can use the Neon framework to integrate Rust with Node.js:

Installing Neon CLI

# Install the Neon CLI globally
npm install -g neon-cli

Creating a Neon Project

# Create a new Neon project
neon new my-neon-project

Rust Code Example in a Neon Project

Below is a simple example of a Rust function exposed to JavaScript using Neon:

Code:

use neon::prelude::*;

// Function to add two numbers
fn add_numbers(mut cx: FunctionContext) -> JsResult<JsNumber> {
    // Get the first argument as a number
    let num1 = cx.argument::<JsNumber>(0)?.value(&mut cx);
    // Get the second argument as a number
    let num2 = cx.argument::<JsNumber>(1)?.value(&mut cx);

    // Return the sum
    Ok(cx.number(num1 + num2))
}

// Register the function with Neon
register_module!(mut cx, {
    cx.export_function("addNumbers", add_numbers)
});

Usage in Node.js

After building the Neon project, you can use it in JavaScript:

Code:

const { addNumbers } = require('./native'); // Import the native module
console.log(addNumbers(5, 3)); // Outputs: 8

Syntax for WASM Integration using wasm-pack

Installing wasm-pack

# Install wasm-pack globally
cargo install wasm-pack

Creating a Rust WASM Project

Code:

# Create a new library project
cargo new --lib my_wasm_project
cd my_wasm_project

Rust Code for WASM

Code:

use wasm_bindgen::prelude::*;

// Export a simple Rust function to WebAssembly
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

Building and Publishing the WASM Module

Code:

# Build the WASM module
wasm-pack build --target bundler

Usage in JavaScript

Code:

import init, { greet } from './pkg/my_wasm_project.js';

async function run() {
    await init();
    console.log(greet("World")); // Outputs: Hello, World!
}

run();

Explanation

    1. Neon: Used for building native modules that execute Rust code in Node.js environments. Suitable for computationally intensive tasks.

    2. wasm-pack: Compiles Rust code into WebAssembly, enabling it to run in JavaScript environments. Great for frontend optimization.

    3. Performance Benefits: Rust’s memory safety and high performance enhance JavaScript-based applications, particularly in areas like cryptography, image processing, or data manipulation.


Additional Considerations

  • Cross-platform Compatibility: Ensure that native modules support the target platforms.
  • Tooling Requirements: Both Neon and wasm-pack have prerequisites, including a Rust environment and Node.js setup.
  • Publishing: Rust-based Node.js packages can be published to NPM for public use.

Rust Language Questions, Answers, and Code Snippets Collection.



Follow us on Facebook and Twitter for latest update.