From 02b42cfb3b0d30538802b79eae14a771279ff14d Mon Sep 17 00:00:00 2001 From: Ismar Besic Date: Mon, 26 Jan 2026 08:43:26 +0100 Subject: [PATCH 1/3] fix: hermes-compiler path for RN 0.82+ in the hermes bytecode plugin --- .changeset/cuddly-months-think.md | 5 +++++ .../utils/getHermesCLIPath.ts | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .changeset/cuddly-months-think.md diff --git a/.changeset/cuddly-months-think.md b/.changeset/cuddly-months-think.md new file mode 100644 index 000000000..6f79b23d7 --- /dev/null +++ b/.changeset/cuddly-months-think.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": patch +--- + +Fix hermes-compiler path for RN 0.82+ in the hermes bytecode plugin diff --git a/packages/repack/src/plugins/HermesBytecodePlugin/utils/getHermesCLIPath.ts b/packages/repack/src/plugins/HermesBytecodePlugin/utils/getHermesCLIPath.ts index c5cad5b33..61b031414 100644 --- a/packages/repack/src/plugins/HermesBytecodePlugin/utils/getHermesCLIPath.ts +++ b/packages/repack/src/plugins/HermesBytecodePlugin/utils/getHermesCLIPath.ts @@ -1,3 +1,4 @@ +import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; @@ -20,7 +21,7 @@ const getHermesOSBin = (): string | null => { /** * Determines the path to the Hermes compiler binary. * - * Defaults to './node_modules/react-native/sdks/hermesc/{os-bin}/hermesc' + * Defaults to './node_modules/hermes-compiler/hermesc/{os-bin}/hermesc' */ export const getHermesCLIPath = (reactNativePath: string): string => { const osBin = getHermesOSBin(); @@ -32,5 +33,19 @@ export const getHermesCLIPath = (reactNativePath: string): string => { ); } + const hermesCompilerPath = path.join( + reactNativePath, + '..', + 'hermes-compiler', + 'hermesc', + osBin, + 'hermesc' + ); + + if (fs.existsSync(hermesCompilerPath)) { + return hermesCompilerPath; + } + + // Fallback to the previous hermesc path in older react native versions, <0.82. return path.join(reactNativePath, 'sdks', 'hermesc', osBin, 'hermesc'); }; From 30321d1679ad1968c2fc79ddc153c85956467ea3 Mon Sep 17 00:00:00 2001 From: Ismar Besic Date: Mon, 2 Feb 2026 13:52:07 +0100 Subject: [PATCH 2/3] test: update mocks --- .../repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts b/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts index 10568640b..6f318f333 100644 --- a/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts +++ b/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts @@ -6,6 +6,7 @@ import { HermesBytecodePlugin } from '../HermesBytecodePlugin/index.js'; jest.mock('node:fs', () => ({ __esModule: true, default: { + existsSync: jest.fn(), promises: { access: jest.fn(), rename: jest.fn(), From 29736500570359b6fce8aba6757ada4cd729c893 Mon Sep 17 00:00:00 2001 From: Ismar Besic Date: Mon, 2 Feb 2026 13:58:24 +0100 Subject: [PATCH 3/3] test: cover hermes cli path for older and newer react native versions --- .../__tests__/HermesBytecodePlugin.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts b/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts index 6f318f333..f93c32447 100644 --- a/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts +++ b/packages/repack/src/plugins/__tests__/HermesBytecodePlugin.test.ts @@ -1,7 +1,9 @@ import fs from 'node:fs'; +import os from 'node:os'; import { type Compiler, ModuleFilenameHelpers } from '@rspack/core'; import execa from 'execa'; import { HermesBytecodePlugin } from '../HermesBytecodePlugin/index.js'; +import { getHermesCLIPath } from '../HermesBytecodePlugin/utils/getHermesCLIPath.js'; jest.mock('node:fs', () => ({ __esModule: true, @@ -143,4 +145,30 @@ describe('HermesBytecodePlugin', () => { expect(execaMock.mock.calls[0][0]).toEqual('path/to/hermesc'); }); }); + + describe('getHermesCLIPath', () => { + const reactNativePath = 'path/to/react-native'; + + it('returns new hermes-compiler path when it exists', () => { + jest.spyOn(os, 'platform').mockReturnValue('darwin'); + jest.mocked(fs.existsSync).mockReturnValue(true); + + const hermesPath = getHermesCLIPath(reactNativePath); + + expect(hermesPath).toBe( + 'path/to/hermes-compiler/hermesc/osx-bin/hermesc' + ); + }); + + it('falls back to legacy hermesc path when hermes-compiler does not exist', () => { + jest.spyOn(os, 'platform').mockReturnValue('darwin'); + jest.mocked(fs.existsSync).mockReturnValue(false); + + const hermesPath = getHermesCLIPath(reactNativePath); + + expect(hermesPath).toBe( + 'path/to/react-native/sdks/hermesc/osx-bin/hermesc' + ); + }); + }); });