3 unstable releases

0.2.1 Oct 15, 2020
0.2.0 Apr 24, 2020
0.1.0 Feb 4, 2020
Download history 5/week @ 2020-07-07 6/week @ 2020-07-14 3/week @ 2020-07-21 4/week @ 2020-07-28 4/week @ 2020-08-04 12/week @ 2020-08-11 8/week @ 2020-08-18 9/week @ 2020-08-25 19/week @ 2020-09-01 6/week @ 2020-09-08 3/week @ 2020-09-15 15/week @ 2020-09-22 83/week @ 2020-09-29 78/week @ 2020-10-06 21/week @ 2020-10-13 8/week @ 2020-10-20

83 downloads per month
Used in node-bindgen


106 lines


Easy way to write native Node.js module using idiomatic Rust


  • Easy: Just write idiomatic Rust code, node-bindgen take care of generating Node.js FFI wrapper codes.
  • Safe: Node.js arguments are checked automatically based on Rust types.
  • Async: Support Async Rust. Async codes are translated into Node.js promises.
  • Class: Rust struct can be access using Node.js classes.
  • Stream: Implement Node.js stream using Rust
  • N-API: Use Node.js N-API which means you don't have to recompile your module.

Compatibility with Node.js version

This project uses v5 of Node N-API. Please see following compatibility matrix.

Following OS are supported:

  • Linux
  • MacOs
  • Windows

Why node-bindgen?

Writing native node-js requires lots of boiler plate code. Node-bindgen generates external "C" glue code from rust code including native module registration. This make it writing node-js module easy and fun.


Getting started

CLI Installation

Install nj-cli command line which will be used to generate native library.

cargo install nj-cli

This is one time step.

Configuring Cargo.toml

Add two dependencies to your projects' Cargo.toml.

Add node-bindgen as a regular dependency (as below):

node-bindgen = { version = "2.1.1" }

Then add node-bindgen's procedure macro to your build-dependencies as below:

node-bindgen = { version = "2.1.1", features = ["build"] }

Then update crate type to cdylib to generate node.js compatible native module:

crate-type = ["cdylib"]


A simple functional example which add two integers. Noticed that you don't need to worry about JS conversion.

use node_bindgen::derive::node_bindgen;

/// add two integer
fn sum(first: i32, second: i32) -> i32 {        
    first + second

Building native library

To build node.js library, using nj-cli to build:

nj-cli build

This will generate Node.js module in "./dist" folder.

Using in Node.js

Then in the Node.js, rust function can invoked as normal node.js function:

$ node
Welcome to Node.js v14.0.0.
Type ".help" for more information.
> let addon = require('./dist');
> addon.sum(2,3)


Function name or method can be renamed instead of default mapping

fn mul(first: i32,second: i32) -> i32 {        
    first * second 

Rust function mul is re-mapped as multiply

Optional argument

Argument can be skipped if it is marked as optional

fn sum(first: i32, second: Option<i32>) -> i32 {        
    first + second.unwrap_or(0)

Then sum can be invoked as sum(10) or sum(10,20)


JS callback are mapped as Rust closure

fn hello<F: Fn(String)>(first: f64, second: F) {

    let msg = format!("argument is: {}", first);


from node:

let addon = require('./dist');

  assert.equal(msg,"argument is: 2");
  console.log(msg);  // print out argument is 2

Callback are supported in Async rust as well.

Support for Async Rust

Async rust function is mapped to Node.js promise.

use std::time::Duration;
use flv_future_aio::time::sleep;
use node_bindgen::derive::node_bindgen;

async fn hello(arg: f64) -> f64 {
    println!("woke and adding 10.0");
    arg + 10.0
let addon = require('./dist');

addon.hello(5).then((val) => {
  console.log("future value is %s",val);

JavaScript class

JavaScript class is supported.

struct MyClass {
    val: f64,

impl MyClass {

    fn new(val: f64) -> Self {
        Self { val }

    fn plus_one(&self) -> f64 {
        self.val + 1.0

    fn value(&self) -> f64 {
let addon = require('./dist');
const assert = require('assert');

let obj = new addon.MyObject(10);
assert.equal(obj.value,10,"verify value works");

There are more features in the examples folder


If you'd like to contribute to the project, please read our Contributing guide.


This project is licensed under the Apache license.


~73K SLoC