{"_id":"@ubjs/node","_rev":"4-8f0ad0ea776b6767e44b5c585a8ad939","name":"@ubjs/node","dist-tags":{"latest":"0.31.0-6"},"versions":{"0.31.0-2":{"name":"@ubjs/node","version":"0.31.0-2","keywords":["uniffi","napi","node-api","rust","ffi","libffi"],"author":{"name":"James Hugman","email":"james@hugman.tv"},"license":"MPL-2.0","_id":"@ubjs/node@0.31.0-2","maintainers":[{"name":"jhugman","email":"james@hugman.tv"}],"homepage":"https://github.com/jhugman/uniffi-bindgen-react-native/tree/main/runtimes/napi","bugs":{"url":"https://github.com/jhugman/uniffi-bindgen-react-native/issues"},"dist":{"shasum":"c9cecb77ec96001341f3819c0b249187c6e35b67","tarball":"https://registry.npmjs.org/@ubjs/node/-/node-0.31.0-2.tgz","fileCount":7,"integrity":"sha512-/gYX3rMELHD6vOZgqT+cbwE/khyXtRTbKNpQG46r9xPgYReOM2kT7LsGPzxm4Mqd8HJaZZHPmXwLG6Gkbl9LlA==","signatures":[{"sig":"MEYCIQCfKE6YxG20Mos+lo2H2E28cNx9wLMZI/wc0lQ7T2YMPwIhAJzJp9yNdo8A3b+E/r2JhLkZlcG+zLqnGBK6xTQPcqFA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ubjs%2fnode@0.31.0-2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":25917},"main":"lib.js","types":"index.d.ts","gitHead":"44a18626be1211b27a3b406940cf0af7e34e7593","_npmUser":{"name":"jhugman","email":"james@hugman.tv"},"repository":{"url":"git+https://github.com/jhugman/uniffi-bindgen-react-native.git","type":"git","directory":"runtimes/napi"},"_npmVersion":"11.12.1","description":"Call Rust libraries from Node.js without hand-written glue — the N-API runtime backend for uniffi-bindgen-react-native.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@ubjs/node-darwin-x64":"0.31.0-2","@ubjs/node-darwin-arm64":"0.31.0-2","@ubjs/node-linux-x64-gnu":"0.31.0-2","@ubjs/node-linux-x64-musl":"0.31.0-2","@ubjs/node-win32-x64-msvc":"0.31.0-2","@ubjs/node-linux-arm64-gnu":"0.31.0-2","@ubjs/node-linux-arm64-musl":"0.31.0-2","@ubjs/node-win32-arm64-msvc":"0.31.0-2"},"_npmOperationalInternal":{"tmp":"tmp/node_0.31.0-2_1779197223766_0.9094173609007727","host":"s3://npm-registry-packages-npm-production"}},"0.31.0-3":{"name":"@ubjs/node","version":"0.31.0-3","keywords":["uniffi","napi","node-api","rust","ffi","libffi"],"author":{"name":"James Hugman","email":"james@hugman.tv"},"license":"MPL-2.0","_id":"@ubjs/node@0.31.0-3","maintainers":[{"name":"jhugman","email":"james@hugman.tv"}],"homepage":"https://github.com/jhugman/uniffi-bindgen-react-native/tree/main/runtimes/napi","bugs":{"url":"https://github.com/jhugman/uniffi-bindgen-react-native/issues"},"dist":{"shasum":"170ae69ec9a0f49a0e72985be7aa6da7a14b8c51","tarball":"https://registry.npmjs.org/@ubjs/node/-/node-0.31.0-3.tgz","fileCount":7,"integrity":"sha512-qNMpi2LICNwxGXZyRF8fSDBSpbezyZbEsydrbiMPJOmtOWr4tmZIEl7jkWGHVGShoBvHfFo4eHp5B4UVP928Cg==","signatures":[{"sig":"MEUCIQCxfBEMhtib1KrOSaQ+1+yAz0p9DW1vg28j9yYKJ0Pl9wIgHKElRYBpNimx37qYiTVnHyEEXdzYSPvyUhq7fnVWGd0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ubjs%2fnode@0.31.0-3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":27497},"main":"lib.js","types":"index.d.ts","gitHead":"dcb5c4ab2350d57f6d26f5fa81a99c77ed86d449","_npmUser":{"name":"jhugman","email":"james@hugman.tv"},"repository":{"url":"git+https://github.com/jhugman/uniffi-bindgen-react-native.git","type":"git","directory":"runtimes/napi"},"_npmVersion":"11.12.1","description":"Call Rust libraries from Node.js without hand-written glue — the N-API runtime backend for uniffi-bindgen-react-native.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@ubjs/node-darwin-x64":"0.31.0-3","@ubjs/node-darwin-arm64":"0.31.0-3","@ubjs/node-linux-x64-gnu":"0.31.0-3","@ubjs/node-linux-x64-musl":"0.31.0-3","@ubjs/node-win32-x64-msvc":"0.31.0-3","@ubjs/node-linux-arm64-gnu":"0.31.0-3","@ubjs/node-linux-arm64-musl":"0.31.0-3","@ubjs/node-win32-arm64-msvc":"0.31.0-3"},"_npmOperationalInternal":{"tmp":"tmp/node_0.31.0-3_1779969114022_0.3611536967089326","host":"s3://npm-registry-packages-npm-production"}},"0.31.0-5":{"name":"@ubjs/node","version":"0.31.0-5","keywords":["uniffi","napi","node-api","rust","ffi","libffi"],"author":{"name":"James Hugman","email":"james@hugman.tv"},"license":"MPL-2.0","_id":"@ubjs/node@0.31.0-5","maintainers":[{"name":"jhugman","email":"james@hugman.tv"}],"homepage":"https://github.com/jhugman/uniffi-bindgen-react-native/tree/main/runtimes/napi","bugs":{"url":"https://github.com/jhugman/uniffi-bindgen-react-native/issues"},"dist":{"shasum":"4a0c36df23fbf0b8946cb8d569522fece10918be","tarball":"https://registry.npmjs.org/@ubjs/node/-/node-0.31.0-5.tgz","fileCount":7,"integrity":"sha512-w1gyA/1H7TiJIQfHD6Zjr673IDfG+1a4hpM0f0krxJr9jlTkrwouFCoNTwpLmSxSWJXtUxkB19Bk0ekxAepOHQ==","signatures":[{"sig":"MEQCIHC4iOpEvh3eYjYVO+sW+KUQlT6hohzyBiUvhTYbIoVMAiArAv03vYoBkVRpjlR8NDWLh68xpPfEn/dWKn2PpyRrmg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ubjs%2fnode@0.31.0-5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":27497},"main":"lib.js","types":"index.d.ts","gitHead":"0f7fc67e8dd98ad43af3787d45c3c570d469a145","_npmUser":{"name":"jhugman","email":"james@hugman.tv"},"repository":{"url":"git+https://github.com/jhugman/uniffi-bindgen-react-native.git","type":"git","directory":"runtimes/napi"},"_npmVersion":"11.17.0","description":"Call Rust libraries from Node.js without hand-written glue — the N-API runtime backend for uniffi-bindgen-react-native.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@ubjs/node-darwin-x64":"0.31.0-5","@ubjs/node-darwin-arm64":"0.31.0-5","@ubjs/node-linux-x64-gnu":"0.31.0-5","@ubjs/node-linux-x64-musl":"0.31.0-5","@ubjs/node-win32-x64-msvc":"0.31.0-5","@ubjs/node-linux-arm64-gnu":"0.31.0-5","@ubjs/node-linux-arm64-musl":"0.31.0-5","@ubjs/node-win32-arm64-msvc":"0.31.0-5"},"_npmOperationalInternal":{"tmp":"tmp/node_0.31.0-5_1787321576427_0.856032089092412","host":"s3://npm-registry-packages-npm-production"}},"0.31.0-6":{"_id":"@ubjs/node@0.31.0-6","bugs":{"url":"https://github.com/jhugman/uniffi-bindgen-react-native/issues"},"dist":{"shasum":"c84cee0a38c149f3fbc16b15725e9ac54cb05394","tarball":"https://registry.npmjs.org/@ubjs/node/-/node-0.31.0-6.tgz","fileCount":7,"integrity":"sha512-VrLj3vnh2TPLb8PItmrK5JJe277rdpTrqiptmb8zySdJ+sGl9Kj1imAE6XSK9zCokPl8lSpgotEQZYCVGZ7egg==","signatures":[{"sig":"MEYCIQCh+QFcg6mCbw7dziZzQ3s6VPBmvouWjyj9TgQYU2iWsgIhAIavQz4CFLrSsHtAoybxGAZd9jXvnn1NY3LgQDdpR2NY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDX4YxQMlboJw2MXTpjlmUKqQjzi7kNKOU3D3K4fXDbtQIgHAU3bMZCIHmXDbxbPkCwNpAs1eV8a6XwXteZd9mElhw="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ubjs%2fnode@0.31.0-6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":27497},"main":"lib.js","name":"@ubjs/node","types":"index.d.ts","author":{"name":"James Hugman","email":"james@hugman.tv"},"gitHead":"3dd1cd1353750dc3bfbbf4bb4d4ccde26b0fbd2e","license":"MPL-2.0","version":"0.31.0-6","_npmUser":{"name":"jhugman","email":"james@hugman.tv"},"homepage":"https://github.com/jhugman/uniffi-bindgen-react-native/tree/main/runtimes/napi","keywords":["uniffi","napi","node-api","rust","ffi","libffi"],"repository":{"url":"git+https://github.com/jhugman/uniffi-bindgen-react-native.git","type":"git","directory":"runtimes/napi"},"_npmVersion":"11.19.0","description":"Call Rust libraries from Node.js without hand-written glue — the N-API runtime backend for uniffi-bindgen-react-native.","directories":{},"maintainers":[{"name":"jhugman","email":"james@hugman.tv"}],"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@ubjs/node-darwin-x64":"0.31.0-6","@ubjs/node-darwin-arm64":"0.31.0-6","@ubjs/node-linux-x64-gnu":"0.31.0-6","@ubjs/node-linux-x64-musl":"0.31.0-6","@ubjs/node-win32-x64-msvc":"0.31.0-6","@ubjs/node-linux-arm64-gnu":"0.31.0-6","@ubjs/node-linux-arm64-musl":"0.31.0-6","@ubjs/node-win32-arm64-msvc":"0.31.0-6"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node_0.31.0-6_1790362774068_0.7282071073704097"}}},"time":{"created":"2026-05-19T13:27:03.665Z","modified":"2026-09-25T18:59:34.702Z","0.31.0-2":"2026-05-19T13:27:03.901Z","0.31.0-3":"2026-05-28T11:51:54.154Z","0.31.0-5":"2026-08-21T14:12:56.567Z","0.31.0-6":"2026-09-25T18:59:34.160Z"},"bugs":{"url":"https://github.com/jhugman/uniffi-bindgen-react-native/issues"},"author":{"name":"James Hugman","email":"james@hugman.tv"},"license":"MPL-2.0","homepage":"https://github.com/jhugman/uniffi-bindgen-react-native/tree/main/runtimes/napi","keywords":["uniffi","napi","node-api","rust","ffi","libffi"],"repository":{"url":"git+https://github.com/jhugman/uniffi-bindgen-react-native.git","type":"git","directory":"runtimes/napi"},"description":"Call Rust libraries from Node.js without hand-written glue — the N-API runtime backend for uniffi-bindgen-react-native.","maintainers":[{"name":"jhugman","email":"james@hugman.tv"}],"readme":"# uniffi-runtime-napi\n\nCall Rust libraries from Node.js — without writing any glue code by hand.\n\n## What it does\n\nYou have a Rust library compiled as a `.dylib` or `.so`. You want to call its functions from JavaScript. Normally, you'd write C bindings, or use a code generator to produce a native addon for each library.\n\nuniffi-runtime-napi takes a different path. It loads your Rust library at runtime, looks up its functions by name, and calls them directly. You describe the function signatures in JavaScript, and uniffi-runtime-napi handles the rest: marshalling values across the boundary, managing memory, and routing callbacks between threads.\n\n## Why this approach\n\nUniFFI uses a small, fixed set of FFI types — integers, floats, byte buffers, callbacks, structs. That set doesn't change no matter which Rust crate you're wrapping. So instead of generating a new native addon for each library, you can build one addon that handles all the types, and drive it with data.\n\nThis has three benefits:\n\n- **Faster development** — change a type description in JS, reload. No Rust recompile for the binding layer.\n- **Simpler packaging** — one prebuilt native addon works with any UniFFI library. Ship the `.dylib` and the generated JS, nothing else.\n- **Easier to add new targets** — writing a bindgen for Bun or Deno means generating JS that talks to the same uniffi-runtime-napi addon.\n\nThe approach is inspired by [node-ffi-rs](https://github.com/zhangyuang/node-ffi-rs), which proved that runtime FFI from Node.js works well in practice. uniffi-runtime-napi narrows the scope to UniFFI's calling conventions, which lets it handle things ffi-rs couldn't — struct-by-value passing, cross-thread callback dispatch, and `BigInt` for 64-bit values.\n\nThis is the FFI backend for [uniffi-bindgen-react-native](https://github.com/jhugman/uniffi-bindgen-react-native). A code generator produces the JavaScript type descriptions; uniffi-runtime-napi executes them.\n\n## How it works\n\nThree steps:\n\n**1. Open a library**\n\n```js\nconst mod = UniffiNativeModule.open(\"/path/to/libfoo.dylib\");\n```\n\nThis calls `dlopen` under the hood.\n\n**2. Register your functions**\n\n```js\nconst nm = mod.register({\n  symbols: {\n    rustbuffer_alloc: \"uniffi_foo_rustbuffer_alloc\",\n    rustbuffer_free: \"uniffi_foo_rustbuffer_free\",\n    rustbuffer_from_bytes: \"uniffi_foo_rustbuffer_from_bytes\",\n  },\n  structs: {},\n  callbacks: {},\n  functions: {\n    uniffi_foo_fn_add: {\n      args: [FfiType.Int32, FfiType.Int32],\n      ret: FfiType.Int32,\n      hasRustCallStatus: true,\n    },\n  },\n});\n```\n\nFor each function, uniffi-runtime-napi looks up the symbol, builds a call descriptor using [libffi](https://sourceware.org/libffi/) (a C library that calls functions whose signatures aren't known until runtime), and returns a callable JavaScript function.\n\n**3. Call them**\n\n```js\nconst status = { code: 0 };\nconst result = nm.uniffi_foo_fn_add(3, 4, status);\n// result === 7\n```\n\nArguments go in as JavaScript values, come out as JavaScript values. Errors from Rust land in the `status` object.\n\n## What crosses the boundary\n\n| JS side | Rust side |\n|---------|-----------|\n| `number` | `i8`–`i32`, `u8`–`u32`, `f32`, `f64` |\n| `BigInt` | `i64`, `u64`, object handles |\n| `Uint8Array` | `RustBuffer` (byte buffers) |\n| `Function` | callback pointers |\n| `Object` | VTable structs (trait implementations) |\n\n## Callbacks and threads\n\nRust code can call back into JavaScript. uniffi-runtime-napi handles two cases:\n\n- **Same thread**: calls the JS function directly (fast).\n- **Different thread**: serializes the arguments, dispatches to the main thread, blocks until the JS function returns.\n\nThis matters for async Rust code that runs work on background threads but needs to call foreign trait methods defined in JS.\n\n## Building\n\n```sh\n# Build the native addon\nnpm run build\n\n# Run tests (builds test fixtures first)\ncd fixtures/test_lib && cargo build && cd ../..\ncd fixtures/uniffi-fixture-simple && cargo build && cd ../..\nnpm test\n```\n\nRequires Rust, Node.js, and a C compiler (for libffi).\n\n## Project structure\n\n```\nsrc/\n  lib.rs          — entry point, library open/close\n  register.rs     — parses definitions, builds CIFs, creates JS functions\n  ffi_type.rs     — the type system: every FFI type as an enum\n  cif.rs          — maps types to libffi descriptors\n  marshal.rs      — converts values between JS and C\n  callback.rs     — callback trampolines (same-thread + cross-thread)\n  structs.rs      — VTable struct building for foreign traits\n  fn_pointer.rs   — wraps C function pointers as callable JS functions\n  library.rs      — dlopen/dlsym wrapper\nfixtures/         — test libraries written in Rust\ntests/            — Node.js test suite\ndocs/             — API reference and design notes\n```\n\n## Status\n\nEarly development. Scalars, buffers, callbacks, cross-thread dispatch, VTables, and async Rust futures all work and are tested.\n","readmeFilename":"README.md"}