This project was initialized from xray
A minimal library for building compiled Node.js
add-ons in Rust
.
| | node12 | node14 | node16 | | --------------------- | ------ | ------ | ------ | | Windows x64 | ✓ | ✓ | ✓ | | Windows x86 | ✓ | ✓ | ✓ | | Windows arm64 | ✓ | ✓ | ✓ | | macOS x64 | ✓ | ✓ | ✓ | | macOS aarch64 | ✓ | ✓ | ✓ | | Linux x64 gnu | ✓ | ✓ | ✓ | | Linux x64 musl | ✓ | ✓ | ✓ | | Linux aarch64 gnu | ✓ | ✓ | ✓ | | Linux aarch64 musl | ✓ | ✓ | ✓ | | Linux arm gnueabihf | ✓ | ✓ | ✓ | | Linux aarch64 android | ✓ | ✓ | ✓ | | FreeBSD x64 | ✓ | ✓ | ✓ |
This library depends on Node-API and requires Node@10.0.0
or later.
We already have some packages written by napi-rs
: node-rs
One nice feature is that this crate allows you to build add-ons purely with the Rust/JavaScript
toolchain and without involving node-gyp
.
You can start from package-template to play with
napi-rs
```rust
fn fibonacci(ctx: CallContext) -> Result
fn fibonaccinative(n: i64) -> i64 { match n { 1 | 2 => 1, _ => fibonaccinative(n - 1) + fibonacci_native(n - 2), } } ```
```rust
extern crate napi_derive;
use napi::{JsObject, Result};
/// exports
is module.exports
object in NodeJS
fn init(mut exports: JsObject) -> Result<()> { exports.createnamedmethod("fibonacci", fibonacci)?; Ok(()) } ```
And you can also create JavaScript
value while registering module:
```rust
extern crate napi_derive;
use napi::{JsObject, Result, Env};
fn init(mut exports: JsObject, env: Env) -> Result<()> { exports.createnamedmethod("fibonacci", fibonacci)?; exports.setnamedproperty("DEFAULTVALUE", env.createint64(100)?)?; Ok(()) } ```
This repository is a Cargo
crate. Any napi-based add-on should contain Cargo.toml
to make it a Cargo crate.
In your Cargo.toml
you need to set the crate-type
to "cdylib"
so that cargo builds a C-style shared library that can be dynamically loaded by the Node executable. You'll also need to add this crate as a dependency.
```toml [package] name = "awesome"
[lib] crate-type = ["cdylib"]
[dependencies] napi = "1" napi-derive = "1"
[build-dependencies] napi-build = "1" ```
And create build.rs
in your own project:
```rust // build.rs extern crate napi_build;
fn main() { napi_build::setup(); } ```
So far, the napi
build script has only been tested on macOS
Linux
Windows x64 MSVC
and FreeBSD
.
See the included test_module for an example add-on.
Install the @napi-rs/cli
to help you build your Rust
codes and copy Dynamic lib
file to .node
file in case you can require
it in your program.
js
{
"package": "awesome-package",
"devDependencies": {
"@napi-rs/cli": "^1.0.0"
},
"napi": {
"name": "jarvis" // <----------- Config the name of native addon, or the napi command will use the name of `Cargo.toml` for the binary file name.
},
"scripts": {
"build": "napi build --release",
"build:debug": "napi build"
}
}
Then you can require your native binding:
js
require('./jarvis.node')
The module_name
would be your package
name in your Cargo.toml
.
xxx => ./xxx.node
xxx-yyy => ./xxx_yyy.node
You can also copy Dynamic lib
file to an appointed location:
bash
napi build [--release] ./dll
napi build [--release] ./artifacts
There are documents which contains more details about the @napi-rs/cli
usage.
Because libraries that depend on this crate must be loaded into a Node executable in order to resolve symbols, all tests are written in JavaScript in the test_module
subdirectory.
To run tests:
sh
yarn build:test
yarn test
| NAPI | NAPI Version | Minimal Node version | Status | | ------------------------------------------------------------------------------------------------------------ | ------------ | -------------------- | ------ | | napicreatearray | 1 | v8.0.0 | ✅ | | napicreatearraywithlength | 1 | v8.0.0 | ✅ | | napicreatearraybuffer | 1 | v8.0.0 | ✅ | | napicreatebuffer | 1 | v8.0.0 | ✅ | | napicreatebuffercopy | 1 | v8.0.0 | ✅ | | napicreatedate | 5 | v11.11.0 | ✅ | | napicreateexternal | 1 | v8.0.0 | ✅ | | napicreateexternalarraybuffer | 1 | v8.0.0 | ✅ | | napicreateexternalbuffer | 1 | v8.0.0 | ✅ | | napicreateobject | 1 | v8.0.0 | ✅ | | napicreatesymbol | 1 | v8.0.0 | ✅ | | napicreatetypedarray | 1 | v8.0.0 | ✅ | | napicreatedataview | 1 | v8.3.0 | ✅ | | napicreateint32 | 1 | v8.4.0 | ✅ | | napicreateuint32 | 1 | v8.4.0 | ✅ | | napicreateint64 | 1 | v8.4.0 | ✅ | | napicreatedouble | 1 | v8.4.0 | ✅ | | napicreatebigintint64 | 6 | v10.7.0 | ✅ | | napicreatebigintuint64 | 6 | v10.7.0 | ✅ | | napicreatebigintwords | 6 | v10.7.0 | ✅ | | napicreatestringlatin1 | 1 | v8.0.0 | ✅ | | napicreatestringutf16 | 1 | v8.0.0 | ✅ | | napicreatestringutf8 | 1 | v8.0.0 | ✅ | | napitype_tag | 8 | v14.8.0, v12.19.0 | ⚠️ |
I have no plan to implement
nape_type_tag
and related API innapi-rs
, because we have implemented arust
replacement in TaggedObject which is more convenient and more compatible.
| NAPI | NAPI Version | Minimal Node Version | Status | | ---------------------------------------------------------------------------------------------------- | ------------ | -------------------- | ------ | | napigetarraylength | 1 | v8.0.0 | ✅ | | napigetarraybufferinfo | 1 | v8.0.0 | ✅ | | napigetbufferinfo | 1 | v8.0.0 | ✅ | | napigetprototype | 1 | v8.0.0 | ✅ | | napigettypedarrayinfo | 1 | v8.0.0 | ✅ | | napigetdataviewinfo | 1 | v8.3.0 | ✅ | | napigetdatevalue | 5 | v11.11.0 | ✅ | | napigetvaluebool | 1 | v8.0.0 | ✅ | | napigetvaluedouble | 1 | v8.0.0 | ✅ | | napigetvaluebigintint64 | 6 | v10.7.0 | ✅ | | napigetvaluebigintuint64 | 6 | v10.7.0 | ✅ | | napigetvaluebigintwords | 6 | v10.7.0 | ✅ | | napigetvalueexternal | 1 | v8.0.0 | ✅ | | napigetvalueint32 | 1 | v8.0.0 | ✅ | | napigetvalueint64 | 1 | v8.0.0 | ✅ | | napigetvaluestringlatin1 | 1 | v8.0.0 | ✅ | | napigetvaluestringutf8 | 1 | v8.0.0 | ✅ | | napigetvaluestringutf16 | 1 | v8.0.0 | ✅ | | napigetvalueuint32 | 1 | v8.0.0 | ✅ | | napigetboolean | 1 | v8.0.0 | ✅ | | napigetglobal | 1 | v8.0.0 | ✅ | | napigetnull | 1 | v8.0.0 | ✅ | | napigetundefined | 1 | v8.0.0 | ✅ |
| NAPI | NAPI Version | Minimal Node Version | Status | | ---------------------------------------------------------------------------------------------------- | ------------ | -------------------- | ------ | | napicoercetobool | 1 | v8.0.0 | ✅ | | napicoercetonumber | 1 | v8.0.0 | ✅ | | napicoercetoobject | 1 | v8.0.0 | ✅ | | napicoercetostring | 1 | v8.0.0 | ✅ | | napitypeof | 1 | v8.0.0 | ✅ | | napiinstanceof | 1 | v8.0.0 | ✅ | | napiisarray | 1 | v8.0.0 | ✅ | | napiisarraybuffer | 1 | v8.0.0 | ✅ | | napiisbuffer | 1 | v8.0.0 | ✅ | | napiisdate | 1 | v8.0.0 | ✅ | | napiiserror | 1 | v8.0.0 | ✅ | | napiistypedarray | 1 | v8.0.0 | ✅ | | napiisdataview | 1 | v8.3.0 | ✅ | | napistrictequals | 1 | v8.0.0 | ✅ | | napidetacharraybuffer | 7 | v13.3.0 | ✅ | | napiisdetachedarraybuffer | 7 | v13.3.0 | ✅ | | napiobjectfreeze | 8 | v14.14.0, v12.20.0 | ✅ | | napiobject_seal | 8 | v14.14.0, v12.20.0 | ✅ |