Rust bindings for writing safe and fast native Node.js modules.



Cargo npm Linux Build Status macOS Build Status Windows Build Status

Rust bindings for writing safe and fast native Node.js modules.

Getting started

Once you have the platform dependencies installed, getting started is as simple as:

$ npm install -g neon-cli
$ neon new my-project

Then see the Hello World guide for writing your first Hello World in Neon!


See our Neon fundamentals docs and our API docs.

N-API Migration Guide

We are hard at work porting Neon to a new backend based on N-API, which will be the basis for Neon 1.0.

Read the new migration guide to learn how to port your Neon projects to N-API!

Platform Support

Operating Systems

Linux macOS Windows


Node 10 Node 12 Node 14

Support for LTS versions of Node and current are expected. If you're using a different version of Node and believe it should be supported, let us know.


Neon supports Rust stable version 1.18 and higher. We test on the latest stable, beta, and nightly versions of Rust.

A Taste...

fn make_an_array(mut cx: FunctionContext) -> JsResult<JsArray> {
    // Create some values:
    let n = cx.number(9000);
    let s = cx.string("hello");
    let b = cx.boolean(true);

    // Create a new array:
    let array: Handle<JsArray> = cx.empty_array();

    // Push the values into the array:
    array.set(&mut cx, 0, n)?;
    array.set(&mut cx, 1, s)?;
    array.set(&mut cx, 2, b)?;

    // Return the array:

register_module!(mut cx, {
    cx.export_function("makeAnArray", make_an_array)

For more examples, see our examples repo.

Get Involved

The Neon community is just getting started and there's tons of fun to be had. Come play! :)

The Rust Bindings community Slack is open to all; use the Slackin app to receive an invitation.


Licensed under either of

at your option.

  • Add ThreadSafeCallback helper to schedule callbacks on the main thread

    Add ThreadSafeCallback helper to schedule callbacks on the main thread

    Hi, this adds a little helper to call a JavaScript function from any rust thread as requested in #197. ~~I'm not sure if this will need a RFC, but I can write one if requested.~~ RFC

    Feedback welcome, especially about the v8 scope setup.

    Inspired by mika-fischer/napi-thread-safe-callback

    opened by geovie 34
  • Error building new project (neon-build)

    Error building new project (neon-build)

    Hi, i just created a new neon project, but it doesn't seems to build ... Here's the log.

    Updating registry ``
    Compiling nod v0.1.0 (file:///Users/jchaput/dev/rust/nod/native)
    Compiling cslice v0.1.1
    Compiling gcc v0.3.43
    error[E0463]: can't find crate for `neon_build`
    1 | extern crate neon_build;
      | ^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
    error: aborting due to previous error
    error: Could not compile `nod`.
    Build failed, waiting for other jobs to finish...
    error: build failed
    neon ERR! cargo build failed
    error Command failed with exit code 1.


    opened by squiidz 26
  • Quest: N-API Support

    Quest: N-API Support

    Prepare, once and future Neon contributors, for our noblest quest yet!

    Pippin: Great! Where are we going?

    We are going to port Neon to Node's new N-API!

    Pippin: Huh?

    I'll explain. N-API brings to Neon the promise of a stable, backwards-compatible ABI—binary compatibility across all future versions of Node.

    This is a big deal.

    Portability across Node versions means Neon will finally be practical for publishing libraries, not just apps: a few prebuilt binaries should be sufficient for all downstream customers to use your native library without ever knowing the difference.

    Pippin: Oh, I get it!

    The stuff of legend, no?

    Our Quest

    Step 1. Create the feature flag

    • [x] Create a cargo feature flag to allow us to concurrently maintain the main Neon codebase along with the experimental N-API support in the same master branch. (Merged!)
    • [x] Set up a test suite specifically for the N-API backend so each task can easily include adding tests (#449)

    Step 2. Implement the port

    • [x] Module contexts and initialization: Implement the neon::context::ModuleContext type and pass it to the module initialization function inside the register_module! macro defined in /src/ The context struct will likely need to encapsulate the underlying napi_env and napi_value as private fields. This can be implemented before we implement functions, with an unimplemented export_function() method for now.
    • [x] Functions: This is probably one of the subtler tasks. See the implementation of neon::types::JsFunction::new(). The Rust callback can be stored as the extra void* data passed to napi_create_function.
    • [x] Function arguments: Implement CallContext::len() and CallContext::argument().
    • [x] Function returns: Implement function return values.
    • [x] this: Implement CallContext::this().
    • [x] Call kinds: Implement CallContext::kind().
    • [x] Function exports: Once we have module contexts and functions implemented, we can implement the ModuleContext::export_function() shorthand method.
    • [x] Objects: See neon::types::JsObject::new() and the neon::object::Object methods.
    • [x] Arrays: See neon::types::JsArray.
    • [x] ArrayBuffers and Buffers: See neon::types::binary and the N-API functions for working with binary data, such as napi_create_arraybuffer, napi_create_buffer, etc.
    • [x] Uninitialized and null: These should be pretty bite-sized. See neon::types::JsUndefined and neon::types::JsNull. @goto-bus-stop
    • [x] Booleans: See neon::types::JsBoolean. @goto-bus-stop
    • [x] Numbers: See neon::types::JsNumber.
    • [x] Strings: See neon::types::JsString. We'll need to explore what binary string representations can be used between the NAN vs N-API runtimes for constructing JS strings.
    • [x] ~Classes: This will require us to figure out how to do unique branding with N-API, but I believe napi_define_class supports this. (Here is one pure C example we can look to for inspiration.)~ <== not needed for functional completeness; see #596
    • [x] Errors: See neon::types::error. We'll need to explore how N-API does throwing and catching errors. - @anshulrgoyal 🔒
    • [x] Conversions: See the uses of neon_runtime::convert::* and the napi_coerce_* functions.
    • [x] Scopes: Luckily, the N-API HandleScope mechanim matches V8's mechanism very closely. See neon::context and the uses of various HandleScope internal types.
    • [x] Tag checks: See uses of neon_runtime::tag::*.
    • [x] ~Task scheduling: See neon::task and neon::context::TaskContext, and the N-API "simply asynchronous operations" API, which uses the same underlying libuv thread pool as Neon's current backend, but with N-API's stable ABI.~ <== not needed for functional completeness; see #596
    • [x] ~Thread-safe callbacks: This can be implemented for N-API once we've merged an implementation for RFC 25, using napi_make_callback.~ <== not needed for functional completeness; see #596
    • [x] Windows Support: Windows requires linking against node.lib and win_delay_load_hook. Create a custom build script to link these on windows.

    We have just a couple remaining items to finish up:

    • [x] Equality comparison of handles - see #666
    • [x] JsBuffer::uninitialized - see #664

    Step 3. Deprecate the legacy runtime

    Once we finish the complete port, we can switch the default feature flags to use the new runtime and publish a new 0.x minor version. Eventually after a few releases we can remove the old runtime completely.

    How to Contribute

    Building N-API-based projects

    To experiment with the N-API runtime or do manual testing, you can create a Neon project that uses the right feature flags. To try it out, you can run:

    neon new --no-default-features --features=napi-latest --neon=path/to/neon my-project

    where path/to/neon is the path on your local filesystem to a local clone of the Neon repo.

    Manual Steps

    The output of neon new executed above will produce a project that fails to build. When using the neon backend, either neon-build should be used with a simple cargo build or neon-cli should be used and neon-build should be removed. If both are used, the project will fail to build.

    There is an RFC ( to replace neon new which will correctly generate a project. The simplest change is to edit native/Cargo.toml:

    • Remove the neon-build dependency
    • Remove build = ""
    • delete native/

    Note: If you create a Neon project nested inside the directory tree of a clone of the Neon repo, you'll need to add the line


    to your Neon project's native/Cargo.toml manifest in order to build the project.

    Adding an N-API primitive

    To add an N-API primitive, you should implement it in pure Rust (using unsafe as necessary, but only as necessary!) in crates/neon-runtime/napi, and call out to the N-API backend exposed through nodejs-sys.

    When the Neon runtime needs to pass around a data structure, you can make two different definitions of the type, separated by testing the feature flag with #[cfg(feature = "...")]. You may sometimes need to refactor the types in the Neon runtime to accommodate differences between the legacy and N-API runtimes.

    Adding a test

    The test/napi directory is the space for adding N-API acceptance tests. You can add native Rust logic to test/napi/native/src and JS logic to test/napi/lib. You can get examples of existing acceptance tests in our existing backend in test/dynamic, which has the same structure.

    Will You Join Us?

    As you can see, the quest ahead of us will be no small feat!

    Pippin: Anyway you'll need people of intelligence on this... thing

    Indeed, but fear not: we're here to help you if you get stuck. And many of these tasks can be a great way to get started with contributing to Neon and even learning Rust.

    Claim one of the tasks today by leaving a comment below or pinging @dherman or @kjvalencik on Slack!

    Pippin: I'm getting one

    opened by dherman 22
  • Switch to GitHub Actions

    Switch to GitHub Actions

    Resolves #528

    • [x] Run cargo test with a NodeJS version matrix and Rust toolchain matrix
    • [x] Specific environment dependencies (apt dependencies etc)
    • [x] Electron settings
    • [x] Generate Documentation
    • [x] Windows build
    • [x] MacOS build
    opened by lhr0909 21
  • [docs] Electron apps - undefined symbol __cxa_pure_virtual

    [docs] Electron apps - undefined symbol __cxa_pure_virtual

    Hey, I'm learning how to set up neon here, and I'm running into an issue where, upon launching electron, I get the error: undefined symbol: __cxa_pure_virtual.

    FWIW, I followed the documentation here. I found #194, but I've interpreted it as the ticket for integrating with electron-rebuild, and that the electron-build-env process was already functional? :thinking: :smile:

    To reproduce:

    1. git clone
    2. cd electron-quick-start
    3. npm i neon-hello
    4. npm i electron-build-env neon-cli --save-dev
    5. $(npm bin)/neon build neon-hello
    6. Edit main.js, adding require('neon-hello') to the top
    7. npm start
    $ npm start                                         
    > [email protected] start /home/mitch/dev/electron-quick-start
    > electron .
    App threw an error during load
    Error: /home/mitch/dev/electron-quick-start/node_modules/neon-hello/native/index.node: undefined symbol: __cxa_pure_virtual
        at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:160:31)
        at Object.Module._extensions..node (internal/modules/cjs/loader.js:722:18)
        at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:160:31)
        at Module.load (internal/modules/cjs/loader.js:602:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:541:12)
        at Function.Module._load (internal/modules/cjs/loader.js:533:3)
        at Module.require (internal/modules/cjs/loader.js:640:17)
        at require (internal/modules/cjs/helpers.js:20:18)
        at Object.<anonymous> (/home/mitch/dev/electron-quick-start/node_modules/neon-hello/lib/index.js:1:168)
        at Object.<anonymous> (/home/mitch/dev/electron-quick-start/node_modules/neon-hello/lib/index.js:5:3)
    A JavaScript error occurred in the main process
    Uncaught Exception:
    Error: /home/mitch/dev/electron-quick-start/node_modules/neon-hello/native/index.node: undefined symbol: __cxa_pure_virtual
        at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:160:31)
        at Object.Module._extensions..node (internal/modules/cjs/loader.js:722:18)
        at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:160:31)
        at Module.load (internal/modules/cjs/loader.js:602:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:541:12)
        at Function.Module._load (internal/modules/cjs/loader.js:533:3)
        at Module.require (internal/modules/cjs/loader.js:640:17)
        at require (internal/modules/cjs/helpers.js:20:18)
        at Object.<anonymous> (/home/mitch/dev/electron-quick-start/node_modules/neon-hello/lib/index.js:1:168)
        at Object.<anonymous> (/home/mitch/dev/electron-quick-start/node_modules/neon-hello/lib/index.js:5:3)
    opened by mitchhentges 20
  • Reuse ThreadsafeFunction in EventQueue

    Reuse ThreadsafeFunction in EventQueue

    Node.js optimizes subsequent ThreadsafeFunction invocations to happen during the same event loop tick, but only if the same instance of ThreadsafeFunction is used. The performance improvement is most noticeable when used in Electron, because scheduling a new UV tick in Electron is very costly.

    With this change EventQueue will use an existing instance of ThreadsafeTrampoline (wrapper around ThreadsafeFunction) if compiled with napi-6 feature, or it will fallback to creating a new ThreadsafeFunction per EventQueue instance.

    Fix: #727

    opened by indutny 18
  • 0.3.2 linker error on macOS

    0.3.2 linker error on macOS

    When I try to build with neon-cli 0.3.2 on macOS it fails with:

    ld: warning: cannot export hidden symbol compiler_builtins::mem::memcpy::h89bf2c29275db9b6 from /var/folders/09/3ccx9hvj499_767y34mtcr900000gn/T/rustc5SpE5s/libcompiler_builtins-4c0e14a54ecf951d.rlib(compiler_builtins-4c0e14a54ecf951d.compiler_builtins.dcjs62au-cgu.0.rcgu.o)
              ld: warning: cannot export hidden symbol compiler_builtins::mem::memmove::hb03f562604dc3076 from /var/folders/09/3ccx9hvj499_767y34mtcr900000gn/T/rustc5SpE5s/libcompiler_builtins-4c0e14a54ecf951d.rlib(compiler_builtins-4c0e14a54ecf951d.compiler_builtins.dcjs62au-cgu.0.rcgu.o)
              ld: warning: cannot export hidden symbol compiler_builtins::mem::memset::h1f53dc51033b23d1 from /var/folders/09/3ccx9hvj499_767y34mtcr900000gn/T/rustc5SpE5s/libcompiler_builtins-4c0e14a54ecf951d.rlib(compiler_builtins-4c0e14a54ecf951d.compiler_builtins.dcjs62au-cgu.0.rcgu.o)
              ld: warning: cannot export hidden symbol compiler_builtins::mem::memcmp::hc5ebea53cd23af68 from /var/folders/09/3ccx9hvj499_767y34mtcr900000gn/T/rustc5SpE5s/libcompiler_builtins-4c0e14a54ecf951d.rlib(compiler_builtins-4c0e14a54ecf951d.compiler_builtins.dcjs62au-cgu.0.rcgu.o)
    Undefined symbols for architecture x86_64:
                "v8::Isolate::ThrowException(v8::Local<v8::Value>)", referenced from:
                    _Neon_Error_Throw in libneon_runtime-0d1b50c0de5edd79.rlib(neon.o)
                    _Neon_Error_ThrowErrorFromUtf8 in libneon_runtime-0d1b50c0de5edd79.rlib(neon.o)
                "v8::Value::IsNumber() const", referenced from:
                    _Neon_Tag_IsNumber in libneon_runtime-0d1b50c0de5edd79.rlib(neon.o)
                "v8::HandleScope::CreateHandle(v8::internal::Isolate*, v8::internal::Object*)", referenced from:
                    _Neon_Class_HasInstance in libneon_runtime-0d1b50c0de5edd79.rlib(neon.o)
              ld: symbol(s) not found for architecture x86_64
              clang: error: linker command failed with exit code 1 (use -v to see invocation)

    with [...] I skipped similar lines, but I can provide full trace.

    Switching back to 0.3.1 (npm install -g [email protected]) fixes the problem.

    Tried with

    • NodeJS v10.15.3, v10.16.3 and v12.12.0.
    • rustc 1.38.0 (625451e37 2019-09-23)
    opened by splix 18
  • A possible memory leak in callbacks/root

    A possible memory leak in callbacks/root


    I was evaluating the new N-API codebase, and found quite fast greatly leaking piece of code. Here's the test repo that will show the leak:

    Now, I did some digging with Valgrind: leak

    As you can see the culprit is in napi_create_reference, called from Root::new. You can dig into the results from the included massif dump! I was not able to collect this data, even by forcing global.gc(), meaning we probably do something wrong in the native side.

    I'd expect this loop to have a steady flat memory profile, the data should be collected in the young-space already...

    opened by pimeys 17
  • New Node.js NAPI

    New Node.js NAPI

    Now that Node.js has brought support for a native API, ABI-compatible across future Node.js versions or even different Node.js engines, are there any plans to use it instead of direct V8 API for Neon's bindings?

    It looks like it could benefit the project, although unclear if it covers all the functionality Neon requires yet.

    beginner friendly 
    opened by RReverser 17
  • Calling async API from node worker threads results in errors

    Calling async API from node worker threads results in errors


    Error message:

    FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place

    opened by kdy1 17
  • Ergonomic function-calling API

    Ergonomic function-calling API

    This PR implements an ergonomic function-calling API using an options object and method chaining. It offers two new methods, JsFunction::call_with() and JsFunction::construct_with(), along with an Arguments trait that enables lightweight syntax for heterogeneously-typed arguments expressed as Rust tuples. It also uses type inference to downcast the result of the function call to an expected type. All together, this makes calling JS functions from Rust much more ergonomic.


    let this = cx.undefined();
    let args = vec![
    let v: Handle<JsArray> = cx, this, args)?


    let v: Handle<JsArray> = f
        .args((cx.number(17), cx.string("hello"))
        .apply(&mut cx)?;

    Previous attempts:


    Also related:

    opened by dherman 0
  • Neon panics when trying to throw an error

    Neon panics when trying to throw an error

    While trying to throw an error with the following code snippet

    let line = match line {
        Ok(s) => s,
        Err(e) => {
            let err_string = context.string(format!(
                "Error converting byte sequence to a string using UTF-8: {}",
            if let Ok(_) = context.throw::<JsString, JsError>(err_string) {
                panic!("Unable to throw error");
            return Ok(());

    Neon panics:

    thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
      left: `PendingException`,
     right: `Ok`', /Users/annika/.cargo/registry/src/
    stack backtrace:
       0:        0x1060eeff1 - std::backtrace_rs::backtrace::libunwind::trace::h1dc1870269c8628b
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/../../backtrace/src/backtrace/
       1:        0x1060eeff1 - std::backtrace_rs::backtrace::trace_unsynchronized::ha7ef99260fae753b
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/../../backtrace/src/backtrace/
       2:        0x1060eeff1 - std::sys_common::backtrace::_print_fmt::hba0b537531255daa
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/sys_common/
       3:        0x1060eeff1 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hec762383110a7685
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/sys_common/
       4:        0x1061047ab - core::fmt::write::h2d5ecb4b9764759c
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/core/src/fmt/
       5:        0x1060ed52a - std::io::Write::write_fmt::h9d7d3ae333151289
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/io/
       6:        0x1060f0745 - std::sys_common::backtrace::_print::h5df039f21c33cd5a
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/sys_common/
       7:        0x1060f0745 - std::sys_common::backtrace::print::ha89aaa3259d98e13
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/sys_common/
       8:        0x1060f0745 - std::panicking::default_hook::{{closure}}::h552de0233eed7dab
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/
       9:        0x1060f032f - std::panicking::default_hook::hf4e8e1e5a5c43b90
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/
      10:        0x1060f0e30 - std::panicking::rust_panic_with_hook::h7c7e0153f3e14d6b
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/
      11:        0x1060f08ce - std::panicking::begin_panic_handler::{{closure}}::h3c7f7ffd2b05c635
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/
      12:        0x1060ef467 - std::sys_common::backtrace::__rust_end_short_backtrace::h3bdf4f6c89eee6ea
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/sys_common/
      13:        0x1060f083a - rust_begin_unwind
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/std/src/
      14:        0x106111c5f - core::panicking::panic_fmt::h88a1b6fbb9084d2c
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/core/src/
      15:        0x106103947 - core::panicking::assert_failed_inner::h755f5b129a6be052
                                   at /rustc/41dfaaa3c66759395835b3af59b22f4f22175dc8/library/core/src/
      16:        0x10610af0e - core::panicking::assert_failed::h9c86835bf37a4d9f
      17:        0x10602a7c4 - neon_runtime::napi::error::throw::h58518d29aaf02ca2
      18:        0x106008c7d - neon::context::internal::Scope<R>::with::h72bed732c507f372
      19:        0x106019126 - core::ops::function::FnOnce::call_once{{vtable.shim}}::hb284d668e109e7e5
      20:        0x106028537 - neon::event::event_queue::ChannelState::callback::h054a30165642d497
      21:        0x10004af13 - __ZN12_GLOBAL__N_16v8impl18ThreadSafeFunction6IdleCbEP9uv_idle_s
      22:        0x1009e9138 - _uv__run_idle
      23:        0x1009e3b84 - _uv_run
      24:        0x100041c00 - __ZN4node5StartEPN2v87IsolateEPNS_11IsolateDataERKNSt3__16vectorINS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENSA_ISC_EEEESG_
      25:        0x100040cc2 - __ZN4node5StartEP9uv_loop_sRKNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEESD_
      26:        0x100040984 - __ZN4node5StartEiPPc
    fatal runtime error: failed to initiate panic, error 5
    opened by AnnikaCodes 1
  • Closure support on JsFunction::new

    Closure support on JsFunction::new

    Is there any method to bind closure function to JsFunction?

    opened by HADMARINE 2
  • feat(napi-8): Support Object.freeze & seal

    feat(napi-8): Support Object.freeze & seal


    This PR introduces support for Object.freeze & Object.seal from N-API Version 8.


    opened by ovr 0
  • Wrap all Node-API functions in neon-runtime to check status

    Wrap all Node-API functions in neon-runtime to check status

    Currently every usage of a Node-API function checks the status. This is almost always required for safety, but it's easy to fix.

    Since all Node-API FFI bindings are defined in a macro and all functions return napi_status, we could wrap them to return Result<(), Status> instead and use the linter to ensure the Result is checked.

    mod node_api {
        extern "C" {
            fn get_undefined(env: Env, result: *mut Value) -> Status;
    pub unsafe fn get_undefined(env: Env, result: *mut Value) -> Result<(), Status> {
        match node_api::get_undefined(env, result) {
            Status::Ok => Ok(()),
            status => Err(status),
    beginner friendly requires safe rust 
    opened by kjvalencik 0
  • Add APIs that convert between `Context` and `napi_env`

    Add APIs that convert between `Context` and `napi_env`

    Closes #611.

    with_raw_env is useful when neon is not used as the "entry" of a native module, so after getting a raw napi_env we need the unsafe API to bootstrap a neon::Context.

    opened by patr0nus 3
  • Make it harder to forge `Throw` tokens

    Make it harder to forge `Throw` tokens

    This PR makes it harder (though not technically impossible) to forge Throw tokens. We already have safety mechanisms in place in case of forged Throw tokens, leading to well-defined panics (as opposed to something unsafe, like undefined behavior). But this should help prevent programs from accidentally saving and reusing a Throw token.

    There is also a test case that still does show how it's technically possible to forge a token, and demonstrates that it still has predictable behavior.

    An alternative that would be even safer would be to place a lifetime on a Throw token, making it impossible to store them in long-lived storage. But this would leak into the type signatures of e.g. NeonResult and APIs that use it, which would add a lot of complexity to Neon for little value. The panic is for a rare enough case that the extra type safety wouldn't be worth it IMO.

    One more change I want to make in this PR is to add !Send phantom data to the Throw type so that it can't be shared outside of its thread.

    opened by dherman 0
  • Overload result type of `Object::get()`

    Overload result type of `Object::get()`

    This PR changes the Object::get() API to return an overloaded result type V: Value instead of JsValue, and automatically performs the downcasting on behalf of the caller. Since it's already a fallible API, this should likely end up being generally more ergonomic.

    This is a backwards-incompatible change, however, and will require migration notes if we decide to go through with it.

    I decided not to implement the same change for JsFunction::call() and JsFunction::construct() because we may not need the backwards-incompatible change if an ergonomic new Arguments builder API ends up being nicer than call() and construct() anyway (and maybe we'd just deprecate those?). I'll implement that in a separate PR.

    opened by dherman 0
  • Detachable `ArrayBuffer`

    Detachable `ArrayBuffer`

    Neon allows allocating ArrayBuffer with bytes with ArrayBuffer::external. Buffers created this way can be detached with napi_detach_array_buffer.

    Unfortunately, Node-API does not provide a way to get the finalize_hint back out of the external ArrayBuffer. Since ArrayBuffer::external is generic, there is no way to safely drop the data when done.

    Neon should provide a special detachable array buffer type that always uses an exactly sized Vec<u8>. Since Neon will provide multiple buffer types that can be detached (according to Node-API), detachable buffers will need to be tagged with napi_type_tag_object, locking the feature to Node-API 8+.

    Unlike dereferencing from a Root, this API will provide a completely safe way to transfer bytes back and forth between JavaScript and Neon without copying data.

    • Create Vec<u8> in Rust
    • Transfer to JavaScript with JsArrayBuffer::detachable(&mut cx, data)
    • Take data back with let data = buf.detach(&mut cx).or_throw(&mut cx)?
    • Re-attach again with JsArrayBuffer::detachable(&mut cx, data)
    opened by kjvalencik 4
  • Add feature to get unsafe reference to ArrayBuffer types in a root

    Add feature to get unsafe reference to ArrayBuffer types in a root

    ArrayBuffer types (ArrayBuffer, Buffer, TypedArray) are all guaranteed not to move in memory. Therefore, it is safe to hold a pointer to the underlying data as long as the type is prevented from being garbage collected (i.e., Root<_>).

    Neon should provide an API for getting a Send + Sync handle to a buffer that can be dereferenced to the underlying bytes. This will allow zero-copy data transfers across threads.

    This method must be unsafe because Neon has no way to guarantee the bytes will not be mutated while reading or writing.

    opened by kjvalencik 0
  • 0.10.0-alpha.2(Sep 17, 2021)

  • 0.10.0-alpha.1(Aug 30, 2021)

  • 0.9.1(Aug 26, 2021)

    • Expose the Finalize trait as neon::types::Finalize so that docs are visible
    • Improved docs and build scripts in create-neon to make release builds more discoverable (
    • Update nan to fix an Electron 13 incompatibility (
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Jul 26, 2021)


    Channel, formerly EventQueue, are now cloneable. Clones share a backing queue to take advantage of an optimization in Node threadsafe functions. Additionally, when specifying Node API 6 or higher (napi-6), calling will return a shared queue (

    The change may cause a performance regression in some pathological use cases (


    EventQueue and EventQueueError have been renamed to Channel and ChannelError respectively to clarify their function and similarity to Rust channels. The types are available as deprecated aliases (


    • Document error causes for Channel::try_send docs (
    • Document neon::object (


    • Fix usage of a removed API in legacy buffers (
    Source code(tar.gz)
    Source code(zip)
  • 0.8.3(Jun 2, 2021)

    • Fix crash caused by non-thread safety in napi_threadsafefunction on early termination (
    • Fix memory leak in Root (
    Source code(tar.gz)
    Source code(zip)
  • 0.8.2(May 18, 2021)

  • 0.8.1(Apr 30, 2021)

  • 0.8.0(Mar 23, 2021)


    • as_slice and as_mut_slice properly handle a null pointer from an empty buffer (
    • Global drop queue added to avoid panics on N-API 6+ when dropping a Root (


    • Added neon::reflect::eval (
    • Added create-neon for creating an N-API project (
    • Added details to the generated by create-neon (


    • Switched N-API tests to cargo-cp-artifact (
    • Added impl<T: Finalize> Finalize for Option<T> (
    • Added a N-API migration guide (


    • Lint fixes (
    • Lint CI enforcement and cargo fmt (
    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Mar 22, 2021)


    • Added JsDate to N-API backend (
    • Implement JsBuffer::unitialized for N-API backend (


    • Do not panic if a Root is leaked after the event loop has stopped (
    • Stubs for features that will not be implemented in the N-API backend are removed (
    • Fix doc URL link (
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Jan 5, 2021)


    Version Selection

    Neon supports a large number of different Node versions which may have different N-API requirements. Neon now supports selecting the minimum required N-API version required by a module. For example, for N-API Version 4:

    neon = { version = "0.7", default-features = false, features = ["napi-4"] }

    If the Neon module is loaded in an older version of Node that does not support that N-API version, a panic message will inform the user.

    Threadsafe Functions

    A prerelease version of EventQueue for calling into the main JavaScript thread from Rust threads can be enabled with the event-queue-api feature flag. The API is considered unstable and may change in the future until the RFC is merged.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Dec 9, 2020)

    The cx.try_catch(..) API has been updated to return T: Sized instead of T: Value ( This API is strictly more powerful and allows users to return both JavaScript and Rust values from try_catch closures.


    • N-API symbols are now loaded dynamically (
    • Build process for N-API is greatly simplified by leveraging dynamic loading (
    Source code(tar.gz)
    Source code(zip)
  • 0.5.3(Nov 24, 2020)

    Bug Fixes

    Upgrade node-gyp (

    • Fix Windows Node 15
    • Fix Apple M1


    Added neon::main macro as a replacement for register_module! (

    Known Issues

    Builds occassionally fail with Windows, Node 15 and npm 7 (

    Source code(tar.gz)
    Source code(zip)
  • 0.5.2(Nov 16, 2020)

  • 0.5.1(Oct 28, 2020)

    Version 0.5.1


    • smallvec is used for collecting arguments and yields a small performance gain when calling JsFunction

    Broader Support

    Thanks to @staltz, neon now builds for both iOS and Android with nodejs-mobile.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Oct 12, 2020)

    Version 0.5.0


    Versions 0.4.1 and 0.4.2 included a breaking change in neon-runtime. At the time, this was considered acceptable because neon-runtime is considered an internal crate and not part of the public API. However, it was discovered, after publishing, that neon-serde, a commonly used crate in the neon ecosystem, contained a direct dependency on neon-runtime. In order to best support users, versions 0.4.1 and 0.4.2 were "yanked" and re-published as 0.5.0.

    Additionally, the team is working with the authors of neon-serde to remove the dependency on neon-runtime to prevent future issues.

    Bug Fixes

    • Fix stack overflow in DowncastError Display impl (
    Source code(tar.gz)
    Source code(zip)
  • 0.4.2(Sep 23, 2020)

  • 0.4.1(Sep 18, 2020)

    Unpublished / Yanked


    Try Catch

    Added the cx.try_catch API of RFC 29. This feature is behind the try-catch-api feature flag.

    Bug Fixes

    • Pass async_context to node::MakeCallback (
    • Cache bust neon if node version changes (
    • Fix debug builds in windows (
    • Fix cross compiling architectures (
    • Fix neon new hanging on Windows (

    CI Improvements

    The Neon Project now uses Github Actions thanks to @lhr0909! As part of this change, CI now runs on all of our supported platforms (macOS, Windows, linux) and Node versions.

    Source code(tar.gz)
    Source code(zip)
The Neon Project
Build crash-free native Node.js plugins with Rust.
The Neon Project
A minimal library for building compiled Node.js add-ons in Rust via Node-API

A minimal library for building compiled Node.js add-ons in Rust via Node-API

Node-API (N-API) for Rust 1.4k Nov 25, 2021
Node.js bindings to the ripgrep library, for fast file searching in JavaScript without child processes!

ripgrepjs ripgrepjs: Node.js bindings to the ripgrep library, for direct integration with JS programs without spawning an extra subprocess! This proje

Annika 0 Nov 7, 2021
Rust Blake hash bindings for Node.js.

@napi-rs/blake-hash Node.js binding for High performance, and no postinstall scripts. Support matrix node12 nod

LongYinan 32 Nov 21, 2021
Facilitating high-level interactions between Wasm modules and JavaScript

wasm-bindgen Facilitating high-level interactions between Wasm modules and JavaScript. Guide | API Docs | Contributing | Chat Built with ?? ?? by The

Rust and WebAssembly 4.6k Nov 24, 2021
A weekly dive into commonly used modules in the Rust ecosystem, with story flavor!

Rust Module of the Week A weekly dive into commonly used modules in the Rust ecosystem, with story flavor! Build status Release Draft The goal The goa

Scott Lyons 19 Sep 5, 2021
Rust Python modules for interacting with Metaplex's NFT standard.

Simple Metaplex Metadata Decoder Install the correct Python wheel for your Python version with pip: pip install metaplex_decoder-0.1.0-cp39-cp39-manyl

Samuel Vanderwaal 7 Nov 15, 2021
Safe Rust bindings to Lua 5.1

rust-lua Copyright 2014 Lily Ballard Description This is a set of Rust bindings to Lua 5.1. The goal is to provide a (relatively) safe interface to Lu

Lily Ballard 116 Nov 17, 2021
mruby safe bindings for Rust

mrusty. mruby safe bindings for Rust mrusty lets you: run Ruby 1.9 files with a very restricted API (without having to install Ruby) reflect Rust stru

Anima 195 Oct 21, 2021
Safe Rust <---> GraalVM Polyglot bindings using procedural macros

The class macro is the primary way to generate bindings to Java types; it will generate a struct (with generics if specified) that implements Pass and Receive and has all the methods you give stubs for. The methods generated can be used like normal rust methods, however mutability is not enforced. The fully-qualified type name should precede a block containing method and constructor stubs. Java primitives like char, int, and byte are aliased to corresponding Rust types.

Alec Petridis 23 Nov 13, 2021
Fastest lz4 compression library in Node.js, powered by napi-rs and lz4-flex.

Lz4 Fastest lz4 compression library in Node.js, powered by napi-rs and lz4-flex. Install this package yarn add lz4-napi API export function compress:

Antonio Musolino 1 Nov 28, 2021
Native Ruby extensions written in Rust

Ruru (Rust + Ruby) Native Ruby extensions in Rust Documentation Website Have you ever considered rewriting some parts of your slow Ruby application? J

Dmitry Gritsay 785 Nov 6, 2021
Easy way to write Node.js module using Rust

node-bindgen Easy way to write native Node.js module using idiomatic Rust Features Easy: Just write idiomatic Rust code, node-bindgen take care of gen

InfinyOn 236 Nov 25, 2021
Benchmark over Node.js binding frameworks in Rust

Benchmark over Node.js binding frameworks in Rust

LongYinan 5 Sep 24, 2021
Native Ruby extensions without fear

Helix ⚠️ Deprecated ⚠️ Sadly, we have made the decision to deprecate this project. While we had hoped to bootstrap the project to a point where it cou

Tilde 2k Nov 17, 2021
lzma-rs binding to Node.js via napi-rs.

@napi-rs/lzma lzma-rs binding to Node.js via napi-rs. ?? Help me to become a full-time open-source developer by sponsoring me on Github Install yarn a

LongYinan 4 Oct 22, 2021
Safe interop between Rust and C++

CXX — safe FFI between Rust and C++ This library provides a safe mechanism for calling C++ code from Rust and Rust code from C++, not subject to the m

David Tolnay 3.3k Nov 25, 2021
A minimalist and safe ECS library for rust!

The full ECS (Entity-Component-System) library. Support an Open Source Developer! ♥️ Composed of two smaller libraries: world_dispatcher: the System p

Joël Lupien 114 Sep 24, 2021
Safe Rust bridge for creating Erlang NIF functions

Rustler Documentation | Getting Started | Example Rustler is a library for writing Erlang NIFs in safe Rust code. That means there should be no ways t

Rusterlium 3k Nov 30, 2021
WebAssembly implementation from scratch in Safe Rust with zero dependencies

wain wain is a WebAssembly INterpreter written in Rust from scratch with zero dependencies. An implementation of WebAssembly. Features: No unsafe code

Linda_pp 196 Nov 8, 2021