Upstreaming the Node-API host into React Native core ☂️
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 25/100
- Tipo de issue
- Funcionalidade
- Clareza
- Precisa de esclarecimento
- Status de atividade
- Pouca atividade
- Stack de tecnologia
- cpp, react-native
- Domínio
- build-system, mobile-dev
Direção de pesquisa
Comece lendo cpp/HermesNapiHost.cpp e cpp/RuntimeNodeApi.cpp; em seguida, revise #222, #91, #368, #412 e a discussão sobre weak-node-api. Esta issue só estará concluída quando o limite mínimo upstream, os pré-requisitos e as questões não resolvidas de scheduling, ambiente e linking de addons estiverem definidos em uma proposta.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
A tracking issue for a long-term ambition: propose the core of this project — creating a Node-API environment and loading an addon into it — for inclusion in React Native itself, and keep the build tooling here.
Nothing here is committed to. The point is to have one place to argue about the seam, and to record what has to be true before a proposal is worth writing.
Why the cut is worth making
The repo currently spans two quite different kinds of work:
- A runtime capability. A TurboModule (
CxxNodeApiHostModule) that creates anapi_envper addon, loads a dynamic library into it, and supplies the host primitives Node-API needs but React Native has no equivalent of — async work, thread-safe function dispatch, fatal-error routing (HostContextincpp/HermesNapiHost.cpp,cpp/RuntimeNodeApi.cpp). - A build system.
cmake-rn,ferric,gyp-to-cmake, the autolinking CLI, the Babel plugin, the prebuild naming and packaging conventions.
(1) is small, general, and belongs anywhere React Native runs. (2) is opinionated, iterates fast, and is a much bigger ask to hand to another project. Asking core to adopt both is likely to sink the whole proposal; asking for (1) alone is close to a one-sentence pitch.
The seam: loading an addon
The natural boundary is the loading primitive itself — the thing #222 describes as a process.dlopen analogue. Core would own "given a reference to an addon, load it and give me its exports"; everything that decides the reference stays here.
Two things to get right in a proposal:
It cannot honestly be process.dlopen(module, filename). Node's takes an absolute filesystem path. On neither of our platforms is there one: on Android the library is lib<name>.so resolved by the dynamic linker out of the APK, on Apple it is @rpath/<name>.framework/<name>. A dlopen-named API that does not accept a path will cost the proposal a long argument about its name. Something honest — load a Node-API addon by library name, resolved the platform's way — is both defensible and a smaller API surface, and the path-shaped case can be an extension later if it ever makes sense.
The naming must not leak across the seam. Whatever core accepts has to be free of our library-name mangling (see #222, #91 and the manifest discussion in #368). If the strategy leaks upstream, we can never change it.
What already argues in favor
- Hermes implements Node-API itself. The engine at our pinned commit ships the whole surface, plus
hermes_napi_create_envandhermes_napi_load_module, which we now use directly (#445). The upstream ask reduces to "expose what the engine already does", not "implement Node-API". - #412 — once React Native ships a Hermes with Node-API, we stop vendoring, and the remaining host code is small enough to read in one sitting.
- The frameworks are no longer preloaded (#351), so addons load on demand and the loading path is ordinary, not a startup-order special case.
The weak-node-api problem
This is the main obstacle, and it is not build tooling, so it does not fall cleanly on our side of the cut.
Addons are compiled independently of any app, so they cannot link against the app's Hermes. Today they link weak-node-api: generated forwarding stubs for every Node-API symbol, backed by a function table the host injects at startup. If the host moves to core, addons still need something to link, and "core gains one TurboModule method" turns into "core gains a method and takes on a shim package" — a much harder sell.
The long-term dissolution is nodejs/node#60916 ("node-api: use v-table to reverse module dependencies", @vmoroz), which inverts the dependency: the runtime exposes its API through vtables reachable from napi_env, and an addon built with NODE_API_MODULE_USE_VTABLE links against nothing at all. That removes the reason weak-node-api exists, and with it the awkward part of the cut. It is upstream, open, and not something to plan a schedule around — but it is the shape of the end state, and worth tracking here.
Until then, options worth thinking through:
- Keep
weak-node-apias a peer package here and propose only the host to core, accepting that addons still need our shim to build. - Have addons link the Hermes/React Native framework directly where the platform allows it, and keep the shim only where it does not.
- Wait for the vtable work and propose the whole thing once addons link nothing.
Prerequisites on our side
Roughly in order, and all independently useful:
- A raw, naming-free loading API in JS — the shape core would eventually own (#222).
- A friendly resolver layered on top of it, taking
{ packageName, path }(#222, #91). - Make the library name data rather than a shared algorithm — a manifest emitted by the linking step (
getLibraryMap()already computes exactly this map) so JS and the linker cannot disagree, and so per-library overrides (#368) have somewhere to live. - Stop vendoring Hermes (#412).
- Settle the addon-declared Node-API version question, which needs an upstream Hermes change either way (#4).
Open questions
- Does
HostContext's threading model (a process-global worker pool plusCallInvokerdispatch) survive contact with core's own scheduling, or would core want to back those primitives differently? - Is the per-addon
napi_env(as in Node) the right model for core, given a React Native app can have several runtimes over its lifetime? - What is the minimum viable proposal — the TurboModule alone, or does it only make sense together with autolinking, so that an app can actually get an addon into its bundle?
Related
#222, #91, #368, #412, #4, #3, #104
- Linguagem predominante
- TypeScript
- Estrelas
- 191
- Forks
- 11
- Merge médio
- 11h 56min
- PRs com merge (30d)
- 2
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de callstackincubator/react-native-node-api
-
Android 🤖
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
-
Sanity check of Hermes source directory via environment variable, when building Android projectsAbertaAndroid 🤖 good first issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
callstackincubator/react-native-node-api#163 · 1 comentário ·
-
enhancement good first issue gyp-to-cmake
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
callstackincubator/react-native-node-api#161 · 3 comentários · 1 reação ·
-
Two test gaps: unverified prebuild `Info.plist` and a missing `.node` fixture in the Babel plugin testsTalvez já em andamento Um pull request vinculado a esta issue está aberto ou já foi mesclado. AbertaAutomatable good first issue
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 15/100
callstackincubator/react-native-node-api#424 · 1 comentário ·
-
Unblock the disabled node-addon-examples (lambdas, `noexcept`, output paths)Talvez já em andamento Um pull request vinculado a esta issue está aberto ou já foi mesclado. Abertagyp-to-cmake
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 55/100
callstackincubator/react-native-node-api#423 · 1 comentário ·
Todas as issues de callstackincubator/react-native-node-api
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia
-
clawsweeper:needs-maintainer-review clawsweeper:needs-product-decision clawsweeper:no-new-fix-pr impact:session-state issue-rating: 🌊 off-meta tidepool P2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
openclaw/openclaw#165245 · 1 comentário · 1 reação ·
Mantenedores costumam responder em até 1 dia
-
agent-canvas bug priority:low ready-for-dev
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 88/100
Mantenedores costumam responder em até 1 dia
-
🐛 bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 61/100
spicetify/marketplace#1262 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 Meio dia Facilidade para iniciantes 68/100
Mantenedores costumam responder em até 1 dia