31 releases (10 stable)

new 1.1.4 Nov 5, 2025
1.1.1 Sep 30, 2025
1.1.0 Jul 26, 2025
1.0.4 Jan 13, 2025
0.0.3 Nov 28, 2023

#38 in FFI

Download history 1982/week @ 2025-07-16 2380/week @ 2025-07-23 2130/week @ 2025-07-30 2528/week @ 2025-08-06 2759/week @ 2025-08-13 3090/week @ 2025-08-20 2642/week @ 2025-08-27 2165/week @ 2025-09-03 1714/week @ 2025-09-10 2049/week @ 2025-09-17 2391/week @ 2025-09-24 2804/week @ 2025-10-01 2699/week @ 2025-10-08 2913/week @ 2025-10-15 3133/week @ 2025-10-22 2569/week @ 2025-10-29

11,686 downloads per month
Used in 26 crates (8 directly)

MIT license

705KB
21K SLoC

ohos-rs

Crates.io Version Platform License: MIT

Please visit the official website: https://ohos.rs

Discussion

Feel free to join our WeChat group!


lib.rs:

High level Node.js N-API binding

napi-rs provides minimal overhead to write N-API modules in Rust.

Feature flags

napi1 ~ napi10

Because Node.js N-API has versions. So there are feature flags to choose what version of N-API you want to build for. For example, if you want build a library which can be used by node@10.17.0, you should choose the napi5 or lower.

The details of N-API versions and support matrix: Node-API version matrix

tokio_rt

With tokio_rt feature, napi-rs provides a tokio runtime in an additional thread. And you can easily run tokio future in it and return promise.

use futures::prelude::*;
use napi_ohos::{CallContext, Error, JsObject, JsString, Result, Status};
use napi::bindgen_prelude::*;
use tokio;

#[napi]
pub fn tokio_readfile(js_filepath: String) -> Result<Buffer> {
    ctx.env.spawn_future_with_callback(
        tokio::fs::read(js_filepath)
          .map(|v| v.map_err(|e| Error::new(Status::Unknown, format!("failed to read file, {}", e)))),
        |_, data| data.into(),
    )
}

latin1

Decode latin1 string from JavaScript using encoding_rs.

With this feature, you can use JsString.as_latin1_string function

serde-json

Enable Serialize/Deserialize data cross JavaScript Object and Rust struct.

#[derive(Serialize, Debug, Deserialize)]
struct AnObject {
    a: u32,
    b: Vec<f64>,
    c: String,
}

#[napi]
fn deserialize_from_js(arg0: JsUnknown) -> Result<JsUndefined> {
    let de_serialized: AnObject = ctx.env.from_js_value(arg0)?;
    ...
}

#[napi]
fn serialize(env: Env) -> Result<JsUnknown> {
    let value = AnyObject { a: 1, b: vec![0.1, 2.22], c: "hello" };
    env.to_js_value(&value)
}

Dependencies

~0.2–13MB
~123K SLoC