perf(napi): shrink release binaries (path remap + build-std without backtrace)#1283
Conversation
Merging this PR will degrade performance by 4.05%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | pm/bun-flat |
839.5 µs | 919.5 µs | -8.7% |
| ❌ | resolver_real[multi-thread] |
245.3 µs | 268.2 µs | -8.56% |
| ❌ | pm/bun-isolated |
953.9 µs | 1,000.4 µs | -4.66% |
| ❌ | pm/yarn-flat |
859.9 µs | 899.9 µs | -4.45% |
| ❌ | pm/pnpm-isolated |
941.4 µs | 980.5 µs | -3.99% |
| ⚡ | pm/npm-flat |
912.5 µs | 853.9 µs | +6.86% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing perf/shrink-release-binaries (001950c) with main (db9fb8b)
Footnotes
-
5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5f8d296fb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…uild wrapper `getOptions()` does not include the clipanion Rest args after `--`; the napi CLI's BuildCommand forwards them separately as `cargoOptions`. Read the same field and merge it after the injected remap `--config` so `node napi/build.mjs -- --locked` behaves like `napi build -- --locked`.
The /rustup mapping alone leaves toolchains/<tc>/lib/rustlib/src/rust/… in panic locations when std is compiled from source. Map the sysroot's rust-src library to /std and its vendored deps to /deps, so a std panic reads /std/alloc/src/raw_vec/mod.rs instead of the 103-char rustup path, and the toolchain name stays out of shipped strings.
Gate -Z build-std on "release build with an explicit --target" instead of the OXC_RESOLVER_BUILD_STD=1 opt-in: rebuilding std is a property of the shipped binaries, not of the workflow that happens to build them. Local dev (debug) builds never touch it. - rust-src present: build-std on (byte-identical to the env-var-gated build, 1,580,752 B on darwin-arm64) - rust-src missing locally: warn and fall back to the prebuilt std - rust-src missing in CI: fail the job instead of silently shipping std's ~200 KiB backtrace machinery - OXC_RESOLVER_BUILD_STD=0 opts out (FreeBSD VM: CI leaks into the VM, and provisioning rust-src there isn't worth it)
Local builds — debug or release — never rebuild std, so dev machines never need the rust-src component; CI=1 reproduces a shipped binary. The local missing-rust-src warning path is gone: in CI (the only place the gate opens) a missing rust-src always fails the job.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7be49164d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Local release builds keep real (clickable) paths and skip the cargo fetch; every shipped binary is built in CI, so artifacts are unchanged. Both size levers — remap and build-std — now share one isCiRelease gate.
Stable cargo silently ignores nightly-only CARGO_UNSTABLE_* env config (verified: without RUSTC_BOOTSTRAP it does a normal prebuilt-std build with no warning) but hard-errors on unknown -Z CLI flags. Route build-std through the cargoOptions passthrough instead, so if the RUSTC_BOOTSTRAP channel unlock ever regresses the release job fails instead of quietly shipping std's backtrace machinery again. Output verified byte-identical (1,580,752 B on darwin-arm64).
## 🤖 New release * `oxc_resolver`: 11.23.0 -> 11.24.0 * `oxc_resolver_napi`: 11.23.0 -> 11.24.0 <details><summary><i><b>Changelog</b></i></summary><p> ## `oxc_resolver` <blockquote> ## [11.24.0](v11.23.0...v11.24.0) - 2026-07-12 ### <!-- 0 -->🚀 Features - expose tsconfig paths resolve method without file existence check ([#1282](#1282)) (by @sapphi-red) - add `ResolveError::TsconfigLoadFailed` for tsconfig read and parse failures ([#1287](#1287)) (by @shulaoda) ### <!-- 2 -->🚜 Refactor - replace cfg-if dependency with std cfg_select! macro ([#1290](#1290)) (by @Boshen) ### <!-- 3 -->📚 Documentation - normalize README sponsor section ([#1273](#1273)) (by @Boshen) ### <!-- 4 -->⚡ Performance - *(cache)* reuse the child path when its parent canonicalizes to itself ([#1288](#1288)) (by @Boshen) - *(napi)* shrink release binaries (path remap + build-std without backtrace) ([#1283](#1283)) (by @Boshen) ### Contributors * @sapphi-red * @Boshen * @renovate[bot] * @shulaoda </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
## 🤖 New release * `oxc_resolver`: 11.24.0 -> 11.24.1 * `oxc_resolver_napi`: 11.24.0 -> 11.24.1 <details><summary><i><b>Changelog</b></i></summary><p> ## `oxc_resolver` <blockquote> ## [11.24.0](v11.23.0...v11.24.0) - 2026-07-12 ### <!-- 0 -->🚀 Features - expose tsconfig paths resolve method without file existence check ([#1282](#1282)) (by @sapphi-red) - add `ResolveError::TsconfigLoadFailed` for tsconfig read and parse failures ([#1287](#1287)) (by @shulaoda) ### <!-- 2 -->🚜 Refactor - replace cfg-if dependency with std cfg_select! macro ([#1290](#1290)) (by @Boshen) ### <!-- 3 -->📚 Documentation - normalize README sponsor section ([#1273](#1273)) (by @Boshen) ### <!-- 4 -->⚡ Performance - *(cache)* reuse the child path when its parent canonicalizes to itself ([#1288](#1288)) (by @Boshen) - *(napi)* shrink release binaries (path remap + build-std without backtrace) ([#1283](#1283)) (by @Boshen) ### Contributors * @sapphi-red * @Boshen * @renovate[bot] * @shulaoda </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
Shrink the shipped
.nodebinaries, ported from rolldown/rolldown#10177. Measured on a matched pair of release runs (baseline vs this branch): −8 to −12% on build-std targets (darwin-arm64 1,738.8 → 1,543.7 KiB, linux-x64-gnu 2,303.2 → 2,104.7 KiB), −0.2 to −0.3% on the remap-only targets (windows, wasm, freebsd).napi/build.mjswrapsnapi build(same clipanion arg parsing,--passthrough) and, only on CI release builds with an explicit--target, injects:--remap-path-prefixfor cargo home →/cargo, rustup home →/rustup, workspace →/oxc-resolver, registry dirs →/deps, std sources →/std, injected as a cargo--configrustflags entry so the.cargo/config.tomltarget rustflags (gnunodelete, wasi stack size) still apply. Panic locations read/deps/sharded-slab-0.1.7/…//std/alloc/…instead of build-machine paths. Migrate to-Ztrim-pathsonce it stabilizes (Tracking Issue for trim-paths RFC 3127 rust-lang/cargo#12137).backtracefeature — drops the ~200 KiB DWARF symbolizer (gimli/object/addr2line), dead weight underpanic = "abort"+strip = "symbols".RUSTC_BOOTSTRAP=1+-Zbuild-std=std,panic_abortCLI flags on the pinned stable toolchain (CLI flags hard-error if the unlock ever breaks; env config would be silently ignored). Excluded: wasm, windows-msvc, FreeBSD (OXC_RESOLVER_BUILD_STD=0).Local builds — debug or release — are untouched: real clickable paths, prebuilt std, no
cargo fetch.CI=1 pnpm build --target <t>reproduces a shipped binary byte-for-byte. A CI release build missingrust-srcfails the job instead of silently shipping the prebuilt std.Accepted behavior change:
RUST_BACKTRACE=1on shipped binaries prints no stack frames — panic message + source location survive. Today's stripped binaries already can't symbolize (=1prints zero frames,=fullmislabels every frame).Known gap: musl artifacts keep unremapped paths — napi-cli force-sets
RUSTFLAGSfor musl, which suppresses config-level rustflags; the fix belongs upstream. build-std still applies there.🤖 Generated with Claude Code