Repository navigation
Add Bun.isStandaloneExecutable - #32583
Conversation
A zero-cost boolean indicating whether the current process is a
`bun build --compile` standalone executable.
The existing way to detect this (`Bun.embeddedFiles.length > 0`)
materializes every embedded file as a heap-backed Blob, which is
wasteful for binaries embedding large assets that only need a yes/no
answer. The other workaround (`Bun.main.startsWith('/$bunfs/')`)
couples user code to an internal path format.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Updated 11:51 PM PT - Jun 21st, 2026
❌ @robobun, your commit 13d2c5f has 2 failures in
🧪 To try this PR locally: bunx bun-pr 32583That installs a local version of the PR into your bun-32583 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds ChangesBun.isStandaloneExecutable property
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/bundler/bundler_compile.test.ts`:
- Line 475: The regex pattern in the stdout assertion for the run object is too
restrictive by hardcoding before=0. Instead of pinning the baseline Blob count
to exactly zero, modify the regex pattern to accept any non-negative number for
the before value while maintaining the real invariant that after is greater than
before. Change the pattern to allow any digit sequence for the before parameter
instead of just 0, ensuring the test only validates the meaningful condition
(after > before) rather than an arbitrary baseline value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ca2a3973-a426-4556-8c9b-71fa278582b2
📒 Files selected for processing (6)
docs/bundler/executables.mdxpackages/bun-types/bun.d.tssrc/jsc/bindings/BunObject+exports.hsrc/jsc/bindings/BunObject.cppsrc/runtime/api/BunObject.rstest/bundler/bundler_compile.test.ts
Measure the Blob count before and after reading isStandaloneExecutable and assert it is unchanged, rather than asserting it is exactly 0. This keeps the assertion strong (reading the property allocates no Blobs) without coupling to unrelated runtime allocation changes.
There was a problem hiding this comment.
I didn't find any issues — the implementation is a straightforward one-line getter following the isMainThread pattern — but since this adds new public API surface and touches packages/bun-types/ (CODEOWNER-protected), it should get a human sign-off.
Extended reasoning...
Overview
This PR adds Bun.isStandaloneExecutable, a read-only boolean on the Bun global that reports whether the process is running as a bun build --compile binary. The change spans six files: a one-line Rust getter (JSValue::js_boolean(global_this.bun_vm().standalone_module_graph.is_some())), C++ property-table wiring in BunObject+exports.h / BunObject.cpp, a TypeScript declaration in packages/bun-types/bun.d.ts, a docs section in executables.mdx, and two tests in bundler_compile.test.ts.
Security risks
None. The getter reads a single boolean from existing VM state (standalone_module_graph.is_some()) — the same field get_embedded_files already branches on directly below it. No user input, no new privilege, no allocation.
Level of scrutiny
Low for correctness — the implementation is mechanical and mirrors isMainThread exactly (same ReadOnly|DontDelete|PropertyCallback attributes, same lazy-prop macro registration). The CodeRabbit nit about hardcoding before=0 in the test was addressed in 4baa8c5. The robobun CI failures are infra-only (Windows arm64 / musl agent provisioning), not test failures.
However, this introduces new public API on the Bun global, and packages/bun-types/ is CODEOWNER-protected. API naming/shape decisions — even tiny ones — are the kind of thing a maintainer should explicitly approve rather than a bot.
Other factors
Test coverage is solid (both the true and false paths, plus a heap-stats assertion that the property doesn't materialize Blobs). No outstanding reviewer comments. Deferring solely because of the new-public-API + CODEOWNER combination, not because of any concern with the code itself.
There was a problem hiding this comment.
Implementation looks correct and follows the established lazy-property pattern, but since this adds a new documented public API to the Bun global it's worth a human sign-off on the name/shape.
Extended reasoning...
Overview
This PR adds Bun.isStandaloneExecutable, a read-only boolean that reports whether the current process is a bun build --compile binary. The change spans six files: a one-line Rust getter that returns js_boolean(vm.standalone_module_graph.is_some()), registration in the export_lazy_prop_callbacks! table, the FOR_EACH_GETTER macro and bunObjectTable entry on the C++ side, a TypeScript declaration, a docs section, and two tests (compiled-true with a Blob-allocation invariant, and a bun -e false case).
Security risks
None. The getter exposes a single boolean derived from existing process state and takes no input. No auth, crypto, filesystem, or network paths are touched.
Level of scrutiny
The implementation is mechanical and mirrors the existing isMainThread / embeddedFiles wiring exactly — low risk of regression. However, the change itself is a new, documented, typed public API on the Bun global, which is a forward-compatibility commitment. Naming and shape decisions for public API surface are product decisions that warrant a maintainer's eyes rather than bot approval.
Other factors
- The one CodeRabbit nit (hardcoded
before=0baseline) was addressed in 4baa8c5 and the thread is resolved. - The single CI failure (
test-tls-client-destroy-soon.json macOS aarch64) is unrelated to this change. - Tests cover both the true and false branches plus the no-Blob-allocation guarantee that motivates the feature.
- No bugs were found by the bug-hunting system.
|
The diff is ready for review. The two new tests ( CI red in #63864 and #63866 is unrelated to this change:
None of these touch |
What does this PR do?
Adds
Bun.isStandaloneExecutable, a read-only boolean that istruewhen the current process is abun build --compilestandalone executable andfalseotherwise.Why
The only public way to detect standalone mode today is
Bun.embeddedFiles.length > 0, butBun.embeddedFilesmaterializes every embedded file as a heap-backedBlob(viadupe_with_content_type). For binaries that embed large native addons this allocates megabytes just to answer a yes/no question.The other workaround,
Bun.main.startsWith('/$bunfs/')(plus the Windows variant), couples user code to an internal path prefix that isn't documented as a stable detection signal.Implementation
The getter reads
global_this.bun_vm().standalone_module_graph.is_some()and returnsjsBoolean. Wired as a lazyPropertyCallbackon the Bun object alongsideisMainThread.How did you verify your code works?
Two tests in
test/bundler/bundler_compile.test.ts:compile/Bun.isStandaloneExecutable: compiles a binary with one embedded asset, assertsBun.isStandaloneExecutable === true, and verifies viaheapStats().objectTypeCounts.Blobthat reading the property allocates zeroBlobobjects (whereas readingBun.embeddedFilesafterwards does).Bun.isStandaloneExecutable is false when not compiled: spawnsbun -eand asserts{ value: false, type: 'boolean' }.Both tests fail on the released bun (
undefined) and pass with this change.