You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Node.js is prolific throughout the server-side world with many projects wanting to repackage the Node.js runtime and the associated standard library/resolution logic/Node.js-isms to offer it to customers such that they can reuse their existing tooling/dependencies.
Notable examples of this:
Rspack
Esbuild
Parcel
Supabase
AWS Lambda
etc
Currently, Node.js cannot be embedded in languages that only support native libraries with a C FFI (Rust, Dotnet, Go, etc).
This leads project maintainers to look for alternative embeddable runtimes that have incomplete Nodejs support, notably Deno (which is a great project in its own right, but lacks certain features that would necessitate consumers rewriting project code).
What is the feature you are proposing to solve the problem?
Expose Node.js embedding capabilities via a C FFI
Offer a static library to allow including Node.js within the embedding binary
What alternatives have you considered?
Embedding Deno
Removing the "Deno" parts of Deno and maintaining a light version with a focus on supporting the Node.js standard library
libnode already exists via the --shared option of configure, and it's been used by other projects like mongodb and Electron to embed Node.js. Check out the documentation and the header file for details.
Thanks for the reference and documentation @joyeecheung! Glad to see there is a pathway to integrate Node.js into an application - and I'm a little embarrassed I missed that part of the documentation.
Any reason this is not officially supported?
Is it that the Node.js team doesn't want to offer API stability guarantees or is it simply not a big enough use case to be a point of focus?
Outside of the Node.js executable, are there more examples of usage?
I think it’s already semi-officially supported. The reason why it’s not fully officially supported is probably mostly that not enough volunteers have stepped up to maintain it or provide support for it. But usually whenever we touch Environment or the NodePlatform we do think about API/ABI breakages and do compatibility patches on older release lines. We also have some cctests and whenever embedders get broken accidentally they will send patches and there usually will be someone reviewing them & try to get them landed (through the flaky CI…). The documentation could probably use more updates and elaboration but not enough people have volunteered to do that either….PR welcomed though :)
Is it that the Node.js team doesn't want to offer API stability guarantees or is it simply not a big enough use case to be a point of focus?
Not sure where the policy document is but I am fairly certain that we do provide API/ABI stability guarantees on LTS.
Just to clarify: libnode is too impractical for us (= mongodb), so we're just building our embedded application as if it is a regular Node.js build from source. 🤷♀️ If somebody did step up to properly maintain libnode as a library that we could use, that would be awesome for us though.
@addaleax does that mean you're vendoring in parts of the Node.js binary source and rewriting the entry points to be callable programmatically?
as in, translating
node ./index.js
to something like
let runtime = NodeWrapper::exec("/path/to/file.js");
runtime.eval();
Do you need to inject napi functions into your Node.js environment from the host application and can you do that with your approach?
In my application I am finishing off integrating Deno before I begin exploring libnode - But now I am wondering if libnode is worth exploring.
I'd be happy to take on work to get it to a point where it could be embedded but if there is too much missing I'd imagine it would require substantial changes which would be difficult to get into Node.js (PRs, reviewing, etc).
Another option is if there was an ability to somehow have an adapter that goes between an existing Node.js process and an external program with the same performance as Napi.
I tried experimenting with using a memory mapped file to act as a place to store shared memory, where the Node.js side has a napi module which opens the shared memory and both the host and Node.js can work with it - but building such an adapter is very cumbersome and limiting (e.g. sharing dynamic data structures like HashMaps and Vectors) so I gave up on that
I have been checking all the issues in this repository related to embedding and we are solving almost all of them, like the hot code reloading @DavidPeicho mentioned.. or other issues like this one: #52282
We are using it in production ready environment and commercially.
Do you have a discord, slack or similar channel where you're discussing the work? I have some basic questions that are better asked outside of the PR itself 🙏
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-staleIssues and PRs exempt from automated stale handling.
label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
Activity
joyeecheung commentedon Mar 31, 2024
libnodealready exists via the--sharedoption ofconfigure, and it's been used by other projects like mongodb and Electron to embed Node.js. Check out the documentation and the header file for details.peng commentedon Apr 1, 2024
Can you show some demo
alshdavid commentedon Apr 1, 2024
Thanks for the reference and documentation @joyeecheung! Glad to see there is a pathway to integrate Node.js into an application - and I'm a little embarrassed I missed that part of the documentation.
Any reason this is not officially supported?
Is it that the Node.js team doesn't want to offer API stability guarantees or is it simply not a big enough use case to be a point of focus?
Outside of the Node.js executable, are there more examples of usage?
EDIT:
I have found this Rust crate which seems to do something with libnode and NAPI https://github.com/branchseer/rust-nodejs
joyeecheung commentedon Apr 1, 2024
I think it’s already semi-officially supported. The reason why it’s not fully officially supported is probably mostly that not enough volunteers have stepped up to maintain it or provide support for it. But usually whenever we touch Environment or the NodePlatform we do think about API/ABI breakages and do compatibility patches on older release lines. We also have some cctests and whenever embedders get broken accidentally they will send patches and there usually will be someone reviewing them & try to get them landed (through the flaky CI…). The documentation could probably use more updates and elaboration but not enough people have volunteered to do that either….PR welcomed though :)
Not sure where the policy document is but I am fairly certain that we do provide API/ABI stability guarantees on LTS.
addaleax commentedon Apr 4, 2024
Just to clarify: libnode is too impractical for us (= mongodb), so we're just building our embedded application as if it is a regular Node.js build from source. 🤷♀️ If somebody did step up to properly maintain libnode as a library that we could use, that would be awesome for us though.
alshdavid commentedon Apr 6, 2024
@addaleax does that mean you're vendoring in parts of the Node.js binary source and rewriting the entry points to be callable programmatically?
as in, translating
to something like
Do you need to inject napi functions into your Node.js environment from the host application and can you do that with your approach?
In my application I am finishing off integrating Deno before I begin exploring
libnode- But now I am wondering iflibnodeis worth exploring.I'd be happy to take on work to get it to a point where it could be embedded but if there is too much missing I'd imagine it would require substantial changes which would be difficult to get into Node.js (PRs, reviewing, etc).
alshdavid commentedon Apr 6, 2024
Another option is if there was an ability to somehow have an adapter that goes between an existing Node.js process and an external program with the same performance as Napi.
I tried experimenting with using a memory mapped file to act as a place to store shared memory, where the Node.js side has a napi module which opens the shared memory and both the host and Node.js can work with it - but building such an adapter is very cumbersome and limiting (e.g. sharing dynamic data structures like HashMaps and Vectors) so I gave up on that
joyeecheung commentedon Apr 13, 2024
To see how to use the existing libnode to embed Node.js into a C++ program, you can check out some of our tests, for example https://github.com/nodejs/node/blob/main/test/embedding/embedtest.cc and https://github.com/nodejs/node/blob/main/test/cctest/test_environment.cc
jasongin commentedon Jun 22, 2024
#43542 adds a simpler ABI-stable API for embedding, that would make
libnodemuch easier to use from other applications and programming languages.DavidPeicho commentedon Nov 28, 2024
We succeeded to have a pretty decent support for
libnodeon our side. However, there are a number of issues that makes it tricky for production:importis leaky. Probably related to Invalidate cache when using import #49442require/importI wouldn't mind helping to make it even easier / more robust to embed, but I would need some pointers especially for the above issues.
viferga commentedon Dec 6, 2024
@alshdavid If you want to use an existing library which already embeds NodeJS, you have this: https://github.com/metacall/core
If you require to use it from Rust, you have the option too:
https://crates.io/crates/metacall
And if you need to distribute it as compiled library, you can also use this: https://github.com/metacall/libnode
We also have other ways of distributing the binaries if you need them I can share them too.
I have been checking all the issues in this repository related to embedding and we are solving almost all of them, like the hot code reloading @DavidPeicho mentioned.. or other issues like this one: #52282
We are using it in production ready environment and commercially.
5 remaining items
alshdavid commentedon Apr 26, 2025
@vmoroz, this is very cool - quite detailed!
Do you have a discord, slack or similar channel where you're discussing the work? I have some basic questions that are better asked outside of the PR itself 🙏
vmoroz commentedon Apr 26, 2025
@alshdavid , I do not think that the Node-API team has a channel on Slack yet.
We can start a new thread in one of the existing channels such as #nodejs.
Alternatively, you can DM me on Discord: https://discord.com/users/443057084444180492
or Slack: https://openjs-foundation.slack.com/team/U07G406DZGW
Or we can discuss it here in this issue or the previous one #23265 . 😃
alshdavid commentedon May 11, 2025
Update on my Rust wrapper for libnode. It's largely feature complete now, with support for;
The only thing missing from the Nodejs side is this one C function and the availability of prebuilt libnode binaries.
github-actions commentedon Nov 8, 2025
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the never-staleIssues and PRs exempt from automated stale handling.
label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
[-]Please make Node.js embeddable (e.g. libnode)[/-][+]Offer a C FFI for Node.js[/+][-]Offer a C FFI for Node.js[/-][+]Offer a C FFI for Node.js embedders[/+]trivikr commentedon Jul 16, 2026
Does node:ffi provide the requested support?
alshdavid commentedon Jul 16, 2026
@trivikr, the original post was about making Nodejs embeddable with a C FFI. Currently it's only embeddable in C++.
I raised a PR that was approved last year but I haven't been able to maintain the PR since then. That would close this issue