Node.js Can Now Be Packaged as an EXE—Evan You Shows It Starts Faster Than Bun
Node.js now supports Single Executable Applications (SEA) with ESM entry points, allowing developers to bundle code and the runtime into a single binary, and benchmarks by Evan You demonstrate that the resulting executable launches faster than Bun's compiled mode.
What Is Node.js SEA?
SEA stands for Single Executable Applications . Traditionally, a Node.js program requires the runtime to be installed, then npm install and node app.js to run. SEA bundles your script together with the V8 engine into a single binary that runs by double‑clicking, without any environment dependencies.
Distribute CLI tools : team members can run a scaffold without installing Node.
Deliver client applications : ship a single clean file to customers.
CI/CD pipelines : reduce build‑environment dependency management.
Edge/embedded : deploy Node apps on resource‑constrained devices.
Unlike Go or Rust, Node.js must bundle the entire V8 engine and your scripts, which makes the implementation technically distinct.
From "Usable" to "Polished": Three Years of Development
2023‑early (v19.7.0): SEA landed but required a cumbersome manual process using an external tool postject to inject a blob into a Node binary, with many low‑level steps and poor documentation.
2023‑2025 (v20 → v24): Iterations added JSON config, asset bundling, V8 code cache, etc., but still relied on postject and only supported CommonJS, leaving ESM projects unable to use SEA.
2026‑01‑26 (v25.5.0): Joyee Cheung moved the injection logic into the Node core, integrating the LIEF library to handle ELF, PE, and Mach‑O formats. SEA can now be built with a single command: node --build-sea sea-config.json Later on 2026‑02‑18, PR #61813 added ESM entry‑point support, completing the feature set.
Why ESM Support Matters
By 2026 most new projects use ESM ( import/export) instead of CommonJS ( require). Previously SEA only accepted CJS entry points, forcing developers to downgrade or abandon SEA. PR #61813 introduced a "mainFormat": "module" field in the SEA config, enabling ESM parsing and features such as import, dynamic import(), top‑level await, and meta‑information ( import.meta.url, import.meta.filename, import.meta.dirname).
Current limitations: ESM mode does not yet support V8 code cache ( useCodeCache) or startup snapshots ( useSnapshot), and import.meta.resolve awaits VFS support.
tsdown --exe: One Command Does It All
With the --build-sea flag, the workflow is simplified, but TypeScript developers still need to compile to JavaScript before building the executable. The upcoming tsdown version (based on Rolldown) will embed a --exe flag to perform "TS compile + bundle + SEA generation" in a single step.
Evan You benchmarked the result: a Node.js SEA built with Rolldown starts faster than bun --compile. However, Bun 1.3.9 later introduced bytecode optimizations that made its startup about 25 % faster than Node.js SEA with code cache.
Hands‑On: Build a Node.js SEA in Five Minutes
Step 1 – Create hello.js:
// hello.js
console.log(`Hello, ${process.argv[2] || 'World'}!`);Step 2 – Create sea-config.json:
{
"main": "hello.js",
"output": "hello"
}Step 3 – Generate the executable: node --build-sea sea-config.json Step 4 – Run it:
./hello Node.js
# Output: Hello, Node.js!On macOS you may need to sign the binary: codesign --sign - hello For ESM projects, adjust the config to include:
{
"main": "app.mjs",
"output": "my-app",
"mainFormat": "module"
}With TypeScript + tsdown, the command simplifies to:
tsdown --exeThe Contributor Behind SEA: Joyee Cheung
Joyee Cheung, a core Node.js contributor, drove the migration of the SEA build process into the core, integrated the LIEF library for cross‑platform binaries, and implemented ESM entry support (PR #61813). She recounts that after early contributors left, development stalled until she revived the project during a vacation, read LIEF documentation, and submitted the pivotal PR.
This story illustrates how critical features in large open‑source projects often rely on the persistence of a few dedicated engineers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
