From 02d278181009080dec56877db0f77782d87a35c5 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 10 Oct 2026 10:44:43 +0000 Subject: [PATCH 1/4] Support Windows on ARM through the x64 package Windows runs the x64 binaries through its x64 emulation, so ARM64 Node now resolves and installs @rescript/win32-x64. Signed-off-by: Christoph Knittel Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + cli/common/bins.cjs | 8 +++++++- packages/@rescript/win32-x64/package.json | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca5ace9c0d0..9f6f401759f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ #### :rocket: New Feature +- Support Windows on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/PRNUMBER #### :bug: Bug fix - Fix JSX preserve mode emitting JSX that means something other than the compiled call, and keep more elements as JSX. https://github.com/rescript-lang/rescript/pull/8754 diff --git a/cli/common/bins.cjs b/cli/common/bins.cjs index a4ba4f62dd3..eabd2c1c34d 100644 --- a/cli/common/bins.cjs +++ b/cli/common/bins.cjs @@ -8,7 +8,13 @@ const path = require("node:path"); const minimumNodeVersion = "20.11.0"; -const target = `${process.platform}-${process.arch}`; +// Windows on ARM runs the x64 toolchain through the operating system's x64 +// emulation, so ARM64 Node uses the x64 package. +const binaryArch = + process.platform === "win32" && process.arch === "arm64" + ? "x64" + : process.arch; +const target = `${process.platform}-${binaryArch}`; const supportedPlatforms = [ "darwin-arm64", diff --git a/packages/@rescript/win32-x64/package.json b/packages/@rescript/win32-x64/package.json index 7755b2ab76e..6ca159ea368 100644 --- a/packages/@rescript/win32-x64/package.json +++ b/packages/@rescript/win32-x64/package.json @@ -45,7 +45,8 @@ "win32" ], "cpu": [ - "x64" + "x64", + "arm64" ], "files": [ "bin.js", From 1a4fce71cbca51625e7d7e67b614abe41c9c749a Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 10 Oct 2026 13:25:32 +0000 Subject: [PATCH 2/4] Link the Windows on ARM CHANGELOG entry Signed-off-by: Christoph Knittel Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f6f401759f..ef31493ac42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ #### :rocket: New Feature -- Support Windows on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/PRNUMBER +- Support Windows on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/8776 #### :bug: Bug fix - Fix JSX preserve mode emitting JSX that means something other than the compiled call, and keep more elements as JSX. https://github.com/rescript-lang/rescript/pull/8754 From bcf3c41b9282382e481c812a232be29f7885c25d Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 10 Oct 2026 15:52:55 +0000 Subject: [PATCH 3/4] Only use the x64 package on Windows 11 on ARM Windows 10 on ARM cannot emulate x64, so it keeps the unsupported-platform error. The target mapping moves to platform.cjs and gets a test. Signed-off-by: Christoph Knittel Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- cli/common/bins.cjs | 24 +++++------------ cli/common/platform.cjs | 43 +++++++++++++++++++++++++++++++ scripts/test.js | 1 + tests/cli_tests/platform_test.mjs | 33 ++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 cli/common/platform.cjs create mode 100644 tests/cli_tests/platform_test.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index ef31493ac42..13a55c630c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ #### :rocket: New Feature -- Support Windows on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/8776 +- Support Windows 11 on ARM by installing the x64 binaries, which Windows runs through its x64 emulation. https://github.com/rescript-lang/rescript/pull/8776 #### :bug: Bug fix - Fix JSX preserve mode emitting JSX that means something other than the compiled call, and keep more elements as JSX. https://github.com/rescript-lang/rescript/pull/8754 diff --git a/cli/common/bins.cjs b/cli/common/bins.cjs index eabd2c1c34d..accd41ad467 100644 --- a/cli/common/bins.cjs +++ b/cli/common/bins.cjs @@ -4,28 +4,18 @@ // The lookup is synchronous so that tools.cjs, the CommonJS entry of // `rescript/tools`, can load it; bins.js re-exports these values for ES modules. +const os = require("node:os"); const path = require("node:path"); +const { getTarget } = require("./platform.cjs"); const minimumNodeVersion = "20.11.0"; -// Windows on ARM runs the x64 toolchain through the operating system's x64 -// emulation, so ARM64 Node uses the x64 package. -const binaryArch = - process.platform === "win32" && process.arch === "arm64" - ? "x64" - : process.arch; -const target = `${process.platform}-${binaryArch}`; +const target = getTarget(process.platform, process.arch, os.release()); -const supportedPlatforms = [ - "darwin-arm64", - "darwin-x64", - "linux-arm64", - "linux-x64", - "win32-x64", -]; - -if (!supportedPlatforms.includes(target)) { - throw new Error(`Platform ${target} is not supported!`); +if (target === undefined) { + throw new Error( + `Platform ${process.platform}-${process.arch} is not supported!`, + ); } const binPackageName = `@rescript/${target}`; diff --git a/cli/common/platform.cjs b/cli/common/platform.cjs new file mode 100644 index 00000000000..1053611faff --- /dev/null +++ b/cli/common/platform.cjs @@ -0,0 +1,43 @@ +// @ts-check + +// Maps the current platform to the platform package (@rescript/) that +// provides its compiler binaries. Kept free of side effects so it can be tested. + +const supportedTargets = [ + "darwin-arm64", + "darwin-x64", + "linux-arm64", + "linux-x64", + "win32-x64", +]; + +// The first Windows 11 build. Windows 10 on ARM only emulates x86, not x64. +const firstWindows11Build = 22000; + +/** + * @param {string} platform `process.platform` + * @param {string} arch `process.arch` + * @param {string} osRelease `os.release()`, e.g. "10.0.22631" on Windows 11 + * @returns {string | undefined} the target, or undefined if unsupported + */ +function getTarget(platform, arch, osRelease) { + // Windows 11 on ARM runs the x64 toolchain through its x64 emulation. + const binaryArch = + platform === "win32" && + arch === "arm64" && + windowsBuild(osRelease) >= firstWindows11Build + ? "x64" + : arch; + const target = `${platform}-${binaryArch}`; + return supportedTargets.includes(target) ? target : undefined; +} + +/** + * @param {string} osRelease + */ +function windowsBuild(osRelease) { + const build = Number(osRelease.split(".")[2]); + return Number.isInteger(build) ? build : 0; +} + +exports.getTarget = getTarget; diff --git a/scripts/test.js b/scripts/test.js index cbf18084779..e5e26839043 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -104,6 +104,7 @@ if (mochaTest) { "10000", "tests/tests/src/**/*_test.mjs", "tests/belt_tests/src/**/*_test.mjs", + "tests/cli_tests/*_test.mjs", // jsx_preserve_test.mjs contains JSX, which Node cannot load; the // file exists to pin the preserved-JSX output. "--ignore", diff --git a/tests/cli_tests/platform_test.mjs b/tests/cli_tests/platform_test.mjs new file mode 100644 index 00000000000..4faa5a1465f --- /dev/null +++ b/tests/cli_tests/platform_test.mjs @@ -0,0 +1,33 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "mocha"; +import { getTarget } from "../../cli/common/platform.cjs"; + +describe("getTarget", () => { + it("maps supported platforms to their own package", () => { + for (const [platform, arch] of [ + ["darwin", "arm64"], + ["darwin", "x64"], + ["linux", "arm64"], + ["linux", "x64"], + ["win32", "x64"], + ]) { + assert.equal(getTarget(platform, arch, "10.0.0"), `${platform}-${arch}`); + } + }); + + it("uses the x64 package on Windows 11 on ARM", () => { + assert.equal(getTarget("win32", "arm64", "10.0.22000"), "win32-x64"); + assert.equal(getTarget("win32", "arm64", "10.0.26100"), "win32-x64"); + }); + + it("rejects Windows 10 on ARM, which cannot emulate x64", () => { + assert.equal(getTarget("win32", "arm64", "10.0.19045"), undefined); + assert.equal(getTarget("win32", "arm64", "unknown"), undefined); + }); + + it("rejects unsupported platforms", () => { + assert.equal(getTarget("win32", "ia32", "10.0.26100"), undefined); + assert.equal(getTarget("linux", "ia32", "6.0.0"), undefined); + assert.equal(getTarget("freebsd", "x64", "14.0"), undefined); + }); +}); From 36da56329569b6292db726facdba2e02b8080fec Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 10 Oct 2026 16:01:28 +0000 Subject: [PATCH 4/4] Add platform.cjs to the artifact list Signed-off-by: Christoph Knittel Co-Authored-By: Claude Opus 5.5 --- packages/artifacts.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/artifacts.json b/packages/artifacts.json index 3e39d26b5c9..20ab33ba762 100644 --- a/packages/artifacts.json +++ b/packages/artifacts.json @@ -10,6 +10,7 @@ "cli/bsc.js", "cli/common/bins.cjs", "cli/common/bins.js", + "cli/common/platform.cjs", "cli/common/runtime.js", "cli/common/tools.cjs", "cli/common/tools.js",