Skip to content

Conversation

@kraenhansen
Copy link
Collaborator

@kraenhansen kraenhansen commented Oct 23, 2025

A first attempt at solving #270.

Merging this PR will:

  • Add a --react-native-package option to the vendor-hermes command, controlling what package name to use when determining the base version of Hermes to use for cloning.
  • Clone Hermes into sdks/node-api-hermes of the React Native package (choosen via --react-native-package ☝️)
  • Refactor the scripts/patch-hermes.rb to allow supplying a REACT_NATIVE_OVERRIDE_HERMES_DIR from the outside to skip calling vendor-hermes internally.

With this, you should be able to clone and override Hermes in the MacOS out-of-tree package of React Native running (in <your-app>/ios):

REACT_NATIVE_OVERRIDE_HERMES_DIR=$(npx react-native-node-api vendor-hermes --silent --react-native-package react-native-macos) pod install

@kraenhansen kraenhansen self-assigned this Oct 23, 2025
@kraenhansen kraenhansen added the enhancement New feature or request label Oct 23, 2025
@kraenhansen kraenhansen requested a review from shirakaba October 23, 2025 22:07
@kraenhansen kraenhansen added the Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) label Oct 23, 2025
@kraenhansen
Copy link
Collaborator Author

@shirakaba I'd love your feedback on this approach.

Copy link
Collaborator

@shirakaba shirakaba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to my understanding, this would mean that RNM users can obtain a suitable value for REACT_NATIVE_OVERRIDE_HERMES_DIR (which they could then set in their CLI, or just write into their Podfile) with:

npx react-native-node-api vendor-hermes --silent --react-native-package react-native-macos

(your example said --react-native-package react-native – correct me if I'm wrong to use --react-native-package react-native-macos!)

I think it's certainly a step forward and makes it possible to proceed, so as it stands currently, it's worth merging already.

Though in terms of an ideal implementation, my impression of this approach is that it treats react-native-macos as a second-class citizen. RNM already has a thousand extra steps to get set up correctly and it would be nice to not have another gotcha along the way for Node-API modules, especially given that this concerns CocoaPods installs, which are very time-consuming.

I wonder if there's any way we can figure out that the script is being called from a react-native-macos app's Podfile. Like, inside packages/host/scripts/patch-hermes.rb, maybe if we're lucky there's some environment variable that will already have been set by the Podfile that we could use to automatically determine that we're running in a react-native-macos app, and if so, pass --react-native-package react-native-macos along to the vendor-hermes script.

else
raise "Hermes patching failed. Please check the output above for errors."
if ENV['REACT_NATIVE_OVERRIDE_HERMES_DIR'].nil?
VENDORED_HERMES_DIR ||= `npx react-native-node-api vendor-hermes --silent '#{Pod::Config.instance.installation_root}'`.strip
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for this to be ||= rather than =? As VENDORED_HERMES_DIR is a local variable, I think it can only be unset at this point?

Suggested change
VENDORED_HERMES_DIR ||= `npx react-native-node-api vendor-hermes --silent '#{Pod::Config.instance.installation_root}'`.strip
VENDORED_HERMES_DIR = `npx react-native-node-api vendor-hermes --silent '#{Pod::Config.instance.installation_root}'`.strip

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's my understanding that Ruby scripts aren't caching requires the same way Node.js would.

I had this originally because it prevents re-execution of the command if the .rb file is (transitively) "required" multiple times.

Comment on lines +7 to +8
if ENV['REACT_NATIVE_OVERRIDE_HERMES_DIR'].nil?
VENDORED_HERMES_DIR ||= `npx react-native-node-api vendor-hermes --silent '#{Pod::Config.instance.installation_root}'`.strip
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of the proposed behaviour for my benefit:

  • If ENV.REACT_NATIVE_OVERRIDE_HERMES_DIR is defined:
    • The env var is used as-is.
    • The script checks whether the directory is exists.
      • If it exists, then good to go.
      • If not, an exception is raised.
  • If ENV.REACT_NATIVE_OVERRIDE_HERMES_DIR is not defined
    • npx react-native-node-api vendor-hermes --silent is called, ultimately vendoring Hermes for react-native (regardless of whether the user is using react-native or react-native-macos.
    • That vendored directory gets set as the value for ENV.REACT_NATIVE_OVERRIDE_HERMES_DIR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly and I agree it would be ideal if we didn't vendor for react-native if this was driven by a MacOS app. Let's make that happen in a follow-up PR, ideally when we actually have a MacOS app in the repo, testing that flow.

@kraenhansen
Copy link
Collaborator Author

@shirakaba

correct me if I'm wrong to use --react-native-package react-native-macos

You're right! I updated the description 👍 My bad.

my impression of this approach is that it treats react-native-macos as a second-class citizen

You're right - once I have a better testing setup, I'd love for us to add calling this conditionally "the right" --react-native-package value, based on what app Podfile is driving the "pod install".

I think we'd want a MacOS test app in the repo to ensure thats a tested path?

@kraenhansen kraenhansen marked this pull request as ready for review October 26, 2025 20:16
@kraenhansen kraenhansen merged commit 7536c6c into main Oct 26, 2025
6 checks passed
@kraenhansen kraenhansen deleted the kh/out-of-tree-hermes-forks branch October 26, 2025 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support vendoring Hermes for out-of-tree platforms

2 participants