Adopt Hermes' first-party Node-API (static_h)#372
Draft
kraenhansen wants to merge 4 commits into
Draft
Conversation
Begin migrating off the kraenhansen/hermes fork + JSI-patching path toward Hermes' first-party Node-API (the static_h branch). - vendor-hermes: shallow-fetch facebook/hermes at pinned static_h SHA 0ae42446d1ae669508368b0a18e60c789f76735d; drop the JSI-header copy step - patch-hermes.rb: rely on REACT_NATIVE_OVERRIDE_HERMES_DIR alone to trigger build-from-source; drop the no-op BUILD_FROM_SOURCE var and the obsolete RCT_USE_PREBUILT_RNCORE / JSI-patch guard - CxxNodeApiHostModule: stub env=nullptr (real env arrives in Phase 2 via hermes_napi_create_env) - bump react-native to 0.87.0-nightly-20260529-88857d22f (+ test-app deps, react-native-test-app 5.x); regenerate lockfile - RN 0.87 fallout: add @types/babel__core, fix test-app tsconfig extends for the tightened @react-native/typescript-config exports map, delete the podspec test asserting the removed guard Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
react-native-test-app 5.x generates the app's ReactTestApp.xcodeproj under the nearest node_modules, which in a workspace is the app-local node_modules (apps/test-app/node_modules/.generated), not the hoisted root. The workspace can also accumulate stale references to a project under a different node_modules. findXcodeProject took the first fileRef unconditionally, which could be the stale (non-existent) reference or the Pods project. Resolve every app project reference and pick the first whose project.pbxproj exists on disk, ignoring Pods.xcodeproj. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Bump @rnx-kit/metro-config to ^2.2.4: 2.1.1 called metro-config's
exclusionList as a bare function, but Metro 0.84 changed that module to a
{ default } export, breaking `react-native start`.
- Gradle wrapper bumped to 9.3.1 by react-native-test-app 5.x's
configureGradleWrapper during pod install (RN 0.87 alignment).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the `env = nullptr` stub in CxxNodeApiHostModule with a real
Node-API environment: cast the JSI runtime to `IHermes`, read the
underlying `vm::Runtime*` via `getVMRuntimeUnsafe()`, and create the env
with `hermes_napi_create_env(vm, nullptr)`. The env is owned by the
runtime and cached on the module (shared across all addons).
This flips the Phase 1 baseline abort (`assert(status == napi_ok)` right
after `napi_create_object(env=nullptr, …)`) green: with
`MOCHA_REMOTE_CONTEXT=allTests` the iOS-sim suite now reports 14 passing
(node-addon-examples getting-started incl. the Rust ferric addon,
buffers, async, and a js-native-api node-test).
Linking note: the RN `hermesvm` framework force-loads `hermesNapi`, and
the public `hermes_napi_*` entry points are exported from it as long as
Hermes is built from a checkout that includes facebook/hermes #2044
("Export public hermes_napi entry points with NAPI macros") — which the
pinned SHA (0ae42446) already contains. No pod-side linker surgery or
source patching is required; just ensure the vendored checkout is
actually at the pinned SHA (a stale pre-#2044 checkout is what stripped
the symbol during bring-up).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b101c95 to
e9dc7e6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
Draft / work in progress. iOS simulator only so far. Opening early for visibility on the approach.
Migrates from the Microsoft/
kraenhansen/hermes-fork Hermes patch flow to Hermes' first-party Node-API, merged onfacebook/hermesbranchstatic_hunderAPI/napi/(targethermesNapi, NAPI v10, built by default). RN has not pulled this in yet, so Hermes is built from source at a pinnedstatic_hSHA.What works now
CxxNodeApiHostModulecasts the JSI runtime toIHermes, reads the low-levelvm::Runtime*viagetVMRuntimeUnsafe(), and creates the env withhermes_napi_create_env(vm, nullptr). The env is owned by the runtime and cached on the module.MOCHA_REMOTE_CONTEXT=allTests→ 14 passing on iOS sim: allnode-addon-examplesgetting-started addons (napi + node-addon-api + Rustferric-example), plusbuffers,async, and ajs-native-apinode-test.Linking
hermesNapi(no pod-side surgery needed)The RN
hermesvmframework already-force_loadshermesNapi, so allnapi_*runtime symbols are exported andhermes_napi_create_env's code is present. The publichermes_napi_*entry points are exported from the framework as long as Hermes is built from a checkout that includes facebook/hermes#2044 "Export public hermes_napi entry points with NAPI macros" — which the pinned SHA already contains. No force_load, no second VM copy, no source patching in this repo. (During bring-up a stale, pre-#2044 vendored checkout briefly stripped the symbol under-fvisibility=hidden; the fix is simply to ensure the vendored checkout is actually at the pinned SHA.)Clean break
Drops RN 0.79–0.81 support, the
kraenhansen/hermesfork tags, JSI-header copying, andrt.createNodeApiEnv(). Targets RN0.87.0-nightly. Old npm releases keep serving old RN versions.Remaining before ready for review
NAPI_VERSION8 → 10 and regenerateweak-node-api+WeakNodeApiInjector.cpp(drop the engine/runtime split)--forcere-vendor at the pinned SHA on the next cold build so the pod matches the pinhermes_napi_host(CallInvoker + worker pool) for async work / thread-safe functionsTest plan
npm run build && npm run prettier:checkreact-native-node-api,cmake-rn,gyp-to-cmake,cmake-file-api)npm run lintMOCHA_REMOTE_CONTEXT=allTests) — 14 passing🤖 Generated with Claude Code