Skip to content

feat(standalone): migrate standalone binaries to Node 26 Single Executable Applications (SEAs) - #10899

Open
joehan wants to merge 7 commits into
mainfrom
jh-sea-hybrid
Open

feat(standalone): migrate standalone binaries to Node 26 Single Executable Applications (SEAs)#10899
joehan wants to merge 7 commits into
mainfrom
jh-sea-hybrid

Conversation

@joehan

@joehan joehan commented Aug 6, 2026

Copy link
Copy Markdown
Member

Description

This PR migrates the firebase-tools standalone binaries to use Node.js 26 native Single Executable Applications (--build-sea) and esbuild, completely replacing the deprecated @yao-pkg/pkg compiler and eliminating the need for external binary injection tools like postject.


Architectural Highlights

  1. Native Node 26 SEA Packaging (--build-sea):
    • Compiles firepit.js and welcome.js with esbuild (--bundle --platform=node --target=node26).
    • Uses Node 26 native SEA compilation to inject JavaScript bundles and compressed assets into the executable without third-party binary injectors.
  2. In-Memory Subprocess Routing & Script Resolution:
    • When child processes are spawned via child_process.fork() or firebase is:node, firepit.js intercepts script arguments at the entrypoint and resolves them via createRequire.
    • Distinguishes executable binaries from JavaScript files to avoid CWD binary name collision errors.
    • Avoids packaging a duplicate 100 MB Node runtime binary inside the asset tarball, saving ~40 MB compressed download size and ~100 MB on-disk extraction footprint.
  3. Cross-Platform Runtime Wrappers:
    • Generates executable runtime wrappers with appropriate #!/bin/sh shebangs and PATH configuration for npm, node, firebase, and shell.
    • Transparently handles npm -c -- subshell script execution for package lifecycle scripts (e.g. protobufjs postinstall) and predeploy hooks (npm run lint, npm run build).
  4. Native Inline Shell Polyfill:
    • Replaces the heavy shelljs and user-home runtime dependencies with a native cross-platform polyfill (mkdir, rm, cp, chmod, ln, ls, cat, exec) backed by Node fs, os.homedir(), and child_process.spawnSync.
  5. Multi-Target Build Script & macOS Code Signing:
    • standalone/build-sea.js downloads official Node 26 binaries and builds executables for:
      • Linux x86_64 (firebase-tools-linux)
      • macOS Apple Silicon (firebase-tools-macos-arm64)
      • macOS Intel (firebase-tools-macos-x64)
      • macOS Universal 2 combined and ad-hoc signed with rcodesign (firebase-tools-macos)
      • Windows x86_64 (firebase-tools-win.exe)
    • Explicitly preserves project templates (including TypeScript init templates) while excluding unnecessary dev build artifacts.
  6. Graceful Logging Emulator Shutdown:
    • WebSocketTransport.stop() terminates active client sockets and includes a safety timeout to prevent shutdown hangs on single Ctrl+C.

Verification & Testing

  • Comprehensive 18-assertion automated test suite (scripts/test-sea-e2e.sh) executed and verified:
    • Clean environment purge & staging download
    • Version command reporting (15.26.0)
    • Global and subcommand help menus
    • Standalone setup diagnostic flag (--tool:setup-check)
    • Subprocess inline evaluation (firebase is:node -e, -p)
    • Subprocess core module resolution (crypto, fs, path, os)
    • Embedded NPM execution & package management (is:npm)
    • External child script execution via fork()
    • Exit code propagation (0 and non-zero)
    • Runtime wrapper execution (runtime/node, runtime/shell with -c --)
    • NPM lifecycle & predeploy script execution
    • Warm boot execution latency benchmark (< 1.5s)
    • Synthetic Firebase project emulator exec interface

…table Applications (SEAs)

- Replace legacy @yao-pkg/pkg with native Node 26 --build-sea and esbuild
- Intercept child process execution via in-memory script routing with createRequire to eliminate duplicate Node binary
- Replace shelljs runtime dependency with native fs/child_process shell polyfill
- Add multi-target build script supporting Linux x64, macOS Universal 2 (arm64 + x64 with lipo), and Windows x64
- Update firepit-builder pipeline to produce SEA artifacts and SHA256 checksums
- Document architecture and build workflows in standalone/README.md
@wiz-9635d3485b

wiz-9635d3485b Bot commented Aug 6, 2026

Copy link
Copy Markdown

Wiz Scan Summary

⚠️ Many findings detected
Many findings were detected, but only a subset of the findings are displayed inline due to API constraints. To view all findings inline, please click here.
Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings 17 Medium 39 Low
Software Management Finding Software Management Findings -
Total 17 Medium 39 Low

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try the Wiz Code extension for VS Code, JetBrains, or Visual Studio.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the Firepit standalone executable builder from @yao-pkg/pkg to Node.js 26's native Single Executable Application (--build-sea) capabilities and esbuild, removing external dependencies like shelljs in favor of a native inline shell polyfill. Feedback on these changes highlights several critical cross-platform and reliability issues: Unix-specific commands (cp -R and find) are used in build-sea.js which will fail on Windows; unconsumed response streams during HTTP redirects or errors in downloadFile can cause socket leaks; and reading directories without verifying they are files in the pipeline script poses an EISDIR crash risk. Additionally, in firepit.js, executing child scripts via createRequire fails to set up require.main properly, and ImitateNode() does not account for leading Node.js options.

Comment thread standalone/build-sea.js Outdated
Comment thread standalone/build-sea.js
Comment thread standalone/build-sea.js
Comment thread standalone/build-sea.js
Comment thread standalone/firepit.js
Comment thread standalone/firepit.js
Comment thread standalone/build-sea.js
Comment thread scripts/firepit-builder/pipeline.js
Comment thread standalone/build-sea.js Fixed
Comment thread standalone/build-sea.js Fixed
Comment thread standalone/build-sea.js Fixed
Comment thread standalone/build-sea.js Fixed
@joehan

joehan commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

/joe-review

Comment thread standalone/build-sea.js Outdated
Comment thread scripts/firepit-builder/pipeline.js
- build-sea.js: use cross-platform fs.cpSync instead of shell cp, add recursive .node file deletion helper, return undefined on rcodesign tool failure, and resume response streams on redirects/errors
- firepit.js: set process.argv[1] and execute child scripts with Module.runMain(), parse leading options into execArgv in ImitateNode()
- pipeline.js: isolate and stage headless artifacts to outputDir before headful build to avoid binary overwrite, add defensive isFile() check for checksum calculation, and fix Prettier formatting
Comment on lines 2 to 11

# Install dependencies
RUN apt-get update && \
apt-get install -y wget tar
apt-get install -y wget tar curl

# Install apple-codesign (rcodesign) for signing and stitching macOS binaries on Linux
RUN curl -fsSL https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.29.0/apple-codesign-0.29.0-x86_64-unknown-linux-musl.tar.gz | tar -xz --strip-components=1 -C /usr/local/bin apple-codesign-0.29.0-x86_64-unknown-linux-musl/rcodesign

# Install hub
RUN curl -fsSL --output hub.tgz https://github.com/github/hub/releases/download/v2.11.2/hub-linux-amd64-2.11.2.tgz

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There's no way we should be curl piping and using this random library for codesigning. Definitely need to find a better, approved approach here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants