Repository navigation
Description
Tracking the Test app (macOS) failure on #372 ("Adopt Hermes' first-party Node-API (static_h)"), and the conditions under which the macOS job can be re-enabled.
Status
The MacOS 💻 label has been removed from #372, so Test app (macOS) no longer runs there. macOS is knowingly deferred — everything else in that PR (iOS, Android, the Node.js tooling) is unaffected.
Why it fails
#372 vendors Hermes from facebook/hermes static_h (pinned SHA) and lets React Native build it from source via REACT_NATIVE_OVERRIDE_HERMES_DIR. On iOS that's RN 0.88.0-nightly, whose Hermes build scripts match. On macOS the app is scaffolded by scripts/init-macos-test-app.ts against react-native-macos@0.81.8 / react-native@0.81.6, and RN 0.81's Hermes build scripts predate the static_h changes we depend on:
-
[RN] [1] Build Hermescfails immediately. RN 0.81'ssdks/hermes-engine/utils/build-hermesc-xcode.shinvokescmake -S … -B … -DJSI_DIR=…with no-DCMAKE_BUILD_TYPE, and wraps it inenv -i, so nothing can be injected from the outside. The pinned Hermes hard-errors in its rootCMakeLists.txt:CMake Error at CMakeLists.txt:46 (message): Please set CMAKE_BUILD_TYPEReproduced locally against the pinned SHA with
react-native-macos@0.81.8'sReactCommon/jsi: configure fails as above, and succeeds once-DCMAKE_BUILD_TYPE=Releaseis added. Upstream RN added that flag in 0.82.0. -
[RN] [2] Build Hermeswould fail next. RN 0.81'sbuild-hermes-xcode.shbuilds--target libhermesand copiesAPI/hermes/hermes.framework. In the pinned Hermes the target ishermesvmand the bundle islib/hermesvm.framework(same rename we handled for Android in Adopt Hermes' first-party Node-API (static_h) #372). RNmainwas updated for this; 0.81 was not. -
Likely next: JSI header skew. Adopt Hermes' first-party Node-API (static_h) #372 drops the step that copied Hermes' JSI headers into RN's
ReactCommon/jsi, on the grounds that the pinned Hermes and RN 0.87+ agree. RN 0.81 does not, so the host module's use ofIHermes/getVMRuntimeUnsafe()may not compile even once (1) and (2) are past.
Note: the second failed phase in CI ([CP] Copy XCFrameworks for weak-node-api) is most likely collateral — an earlier run with the same Hermesc error reported that phase as passing. Confirm rather than assume once the build gets further.
What gates re-enabling macOS
react-native-macos must ship a release based on React Native ≥ 0.82 (that release carries both the CMAKE_BUILD_TYPE fix and the hermesvm rename). Today latest is 0.81.9, next is 0.81.0, nightly is 0.78.4 — there is no 0.82+ line at all, so bumping the pin within 0.81.x buys nothing.
When that lands:
- Bump
REACT_NATIVE_MACOS_VERSION/REACT_NATIVE_VERSIONinscripts/init-macos-test-app.ts(they are peer-locked; keep them in lockstep). - Re-add the
MacOS 💻label to the relevant PR — the job in.github/workflows/check.ymlis already label-gated, so no workflow change is needed. - Expect to work through (3) above: JSI/
IHermescompatibility against the newer react-native-macos.
A local workaround is possible in the meantime (patch react-native-macos's two Hermes scripts from vendor-hermes), but it papers over a gap that keeps widening with every further static_h change, and does nothing about (3). Preferred order is: wait for upstream, then bump.
Related: #372, #391 (captures the raw xcodebuild log so a script phase failure is diagnosable at all).
Activity
kraenhansen commentedon Aug 13, 2026
Extra step once this is unblocked: move macOS onto the prebuilt Hermes archive
Apple platforms no longer build Hermes as part of the app build. A new
prebuilt-hermescommand builds the pinned commit once into an archive, whichscripts/patch-hermes.rbhands to React Native viaHERMES_ENGINE_TARBALL_PATH(branchclaude/hermes-source-build-cache-zk13mc).react-native-macoswas deliberately left on the old source path, since the archive is only produced and exercised for the iOS platforms today:So the re-enabling checklist in the issue body gains a fourth item — and note that item 3 (JSI header skew) is the same constraint that decides whether this works at all, since the archive is compiled against a specific package's
ReactCommon/jsi:react-native-macos≥ 0.82 is in place:react_native_package == "react-native-macos"branch frompackages/host/scripts/patch-hermes.rb, and pass--platform macosxfor that package instead (prebuilt-hermesalready takes it;hermes-prebuilt.tsdeliberately keepsmacosxout of the universal XCFramework becausehermes-engine.podspecvendors macOS as a plain framework).Resolve prebuilt Hermes name/Cache prebuilt Hermes/Build prebuilt Hermessteps to thetest-macosjob in.github/workflows/check.yml, mirroringtest-ios. Without them that job pays a full macOS Hermes build on every run.react-native-macos's vendoredhermes-engine.podspecstill honoursHERMES_ENGINE_TARBALL_PATHand expects the samedestroot/layout. The archive is built for whichever React Native package the app resolves, so areact-native-macosarchive gets its own name and never collides with the iOS one — but a podspec that reads the tarball differently would need handling here..github/workflows/hermes-prebuilt.ymlto publish the macOS archive alongside the iOS one, otherwise macOS consumers fall back to building locally.Generated by Claude Code
Use the prebuilt Hermes archive for iOS builds
Use the prebuilt Hermes archive for iOS builds
Use the prebuilt Hermes archive for iOS builds (#441)
Use the prebuilt Hermes archive for iOS builds (#441)
Use the prebuilt Hermes archive for iOS builds (#441)
Use the prebuilt Hermes archive for iOS builds (#441)
Use the prebuilt Hermes archive for iOS builds (#441)
kraenhansen commentedon Oct 31, 2026
Status update (2026-10-31): react-native-macos 0.83.0 is out, but it doesn't unblock macOS
react-native-macos@0.83.0is nowlatest. I checked its npm tarball against the three failures listed in the issue body.Fixed in 0.83.0
Build Hermesc:sdks/hermes-engine/utils/build-hermesc-xcode.shnow passes-DCMAKE_BUILD_TYPE=Release.Build Hermes:build-hermes-xcode.shbuilds--target hermesvmand copieslib/hermesvm.framework, andhermes-engine.podspecvendorshermesvm.frameworkfor macOS.The matching versions would be
react-native-macos@0.83.0withreact-native@0.83.10, which it peer-pins exactly, andreact@^19.2.0.Still blocking: (3) JSI skew, and it's worse than this issue expected
The issue body expected (3) to affect only the host module's
IHermesinclude. In fact Hermes itself won't compile:build-hermes-xcode.shpasses-DJSI_DIR=${REACT_NATIVE_PATH}/ReactCommon/jsi. Hermes' rootCMakeLists.txtgivesJSI_DIRpriority over its ownAPI/jsi, so the pinnedstatic_hHermes (5a795c9f) gets compiled against react-native-macos 0.83's JSI.API/hermes/hermes.cppoverrides roughly 30 JSI methods that RN 0.83'sjsi.hdoesn't declare, such ascreateUint8Array,createTypeErrorand the othercreate*Errormethods,serialize/deserialize, andIRuntime/setRuntimeData. Hermes'jsi.hhas 95 pure virtuals; RN 0.83's has 59.API/hermes/hermes.hincludes<jsi/hermes-interfaces.h>, which RN 0.83 doesn't ship. 0.83 has only the olderjsi/hermes.h.packages/host/cpp/CxxNodeApiHostModule.cppincludes the same missing header.IHermesUUID is the same in both versions (0xe85cfa22…), so the runtimecastInterfacewould still work. The break is entirely at compile time.How far each react-native release's
ReactCommon/jsi/jsiis from the pinned Hermes'API/jsi/jsi(excludingtest/):hermes-interfaces.hItem 4 (moving macOS onto the prebuilt Hermes archive) doesn't get around this, because the archive is compiled against the same
ReactCommon/jsi.Revised gate
Re-enabling macOS now needs react-native-macos built on React Native ≥ 0.87, the first release whose JSI matches the pinned Hermes (0.86 is close: one file differs). "≥ 0.82" is no longer enough. Today react-native-macos has nothing newer than 0.83.0 on any dist-tag, including
nightly, while core react-native is at 0.88.1.The workaround would be to bring back the JSI-header overlay that #372 removed, this time for react-native-macos only. That would force all of RN 0.83 to compile against roughly 0.87-level JSI, and
ReactInstance.cppwould seeIHermesdefined twice, once fromjsi/hermes.hand once fromhermes-interfaces.h. That's the kind of widening local patch this issue argues against, so I haven't pursued it. The re-enabling checklist in the issue body still applies, with "≥ 0.82" read as "≥ 0.87".Generated by Claude Code
Use the prebuilt Hermes archive for iOS builds (#441)
Use the prebuilt Hermes archive for iOS builds (#441)