node2exe
v1.1.3
Published
Easily convert your Node.js application into an executable with SEA (Single Executable Application)
Downloads
15
Maintainers
Readme
node2exe
🚀 Easily convert your Node.js application into an executable with SEA (Single Executable Application).
Supported on: Windows, macOS, Linux
Made with ❤️ by Klicat - France
Installation
npm install --save-dev node2exeUsage
Option 1: Direct command
In your project, run:
npx node2exeOption 2: With version in filename
npx node2exe -VThis generates app-1.0.0.exe (or app-1.0.0 on macOS/Linux) based on your package.json version.
Option 3: NPM script
Add to your package.json:
{
"scripts": {
"build:exe": "node2exe"
}
}Then run:
npm run build:exe
npm run build:exe -- -V # with versionRequirements
- Node.js 24+ (with SEA support)
- A file specified in
package.jsonmainfield (e.g.,server.js,app.js,index.js) - A
package.jsonfile
Note: The executable name is based on the main field filename. If not defined, it defaults to app.
Output by platform
Windows
- Generates:
app.exe(Windows executable) - Run: Double-click or
app.exe
macOS
- Generates:
app(macOS executable) - Run:
./appin terminal - Note: Automatic code signing
Linux
- Generates:
app(Linux executable) - Run:
./appin terminal
How it works
- ✅ Reads entry point from
package.jsonmainfield - ✅ Installs
postjectif not already present - ✅ Creates
sea-config.jsonautomatically - ✅ Generates the SEA blob
- ✅ Creates the executable for your platform
- ✅ Cleans up temporary files
Example
# Installation
npm install --save-dev node2exe
# Usage
npx node2exe
# Result
# ✅ app.exe created! (Windows)
# ✅ app created! (macOS/Linux)Generated files
app.exe/app- Your final executable (ready to distribute)sea-config.json- SEA configuration (optional after creation)node_modules/- Contains postject and dependencies
Important: CommonJS (require) vs ES Modules (import)
⚠️ SEA (Single Executable Applications) only supports CommonJS modules (require), not ES Modules (import).
However, with node2exe's automatic bundling, you can write in ES Modules! Here's how:
How it works:
- You write ES Modules:
import colors from 'colors';
import https from 'https';
console.log('Hello'.blue);- esbuild automatically converts to CommonJS:
const colors = require('colors');
const https = require('https');
console.log('Hello'.blue);- SEA runs the CommonJS version in the executable
✅ Using ES Modules (Recommended for new projects)
Don't forget to add "type": "module" to package.json:
{
"name": "my-app",
"version": "1.0.0",
"type": "module",
"main": "server.js"
}Your code:
import express from 'express';
import colors from 'colors';
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
console.log(colors.blue('→ Request received on /'));
res.send('Hello World from Express!');
});
app.listen(PORT, () => {
console.log(colors.green(`✓ Server running on http://localhost:${PORT}`));
});✅ Using CommonJS (Traditional)
{
"name": "my-app",
"version": "1.0.0",
"main": "server.js"
}Your code:
const express = require('express');
const colors = require('colors');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
console.log(colors.blue('→ Request received on /'));
res.send('Hello World from Express!');
});
app.listen(PORT, () => {
console.log(colors.green(`✓ Server running on http://localhost:${PORT}`));
});⚠️ Limitations with ES Modules
Some advanced ES Module features may not work:
- Dynamic imports -
import()at runtime - Top-level await -
awaitoutside async function - Circular dependencies - complex import cycles
Simple rule: If your imports look straightforward, they'll work!
Official documentation: https://nodejs.org/api/single-executable-applications.html
"The single executable application feature currently only supports running a single embedded script using the CommonJS module system."
Executable Naming
The name of your executable is automatically determined by the main field in your package.json:
Example 1: With main defined
{
"name": "my-project",
"main": "server.js",
"version": "1.0.0"
}Running npx node2exe creates: server.exe (or server on macOS/Linux)
Example 2: Default behavior
{
"name": "my-project",
"version": "1.0.0"
}Running npx node2exe creates: app.exe (default name, since main is not defined)
Example 3: With version flag
{
"name": "my-project",
"main": "index.js",
"version": "2.5.0"
}Running npx node2exe -V creates: index-2.5.0.exe
How it works:
- node2exe reads the
mainfield frompackage.json - Extracts the filename without extension:
server.js→server - Uses that as the executable name
- If
mainis not defined, defaults toapp - With
-Vflag, appends the version:server-1.0.0.exe
Notes
- The created executable includes all your code and Node.js
- No external dependencies required to run
- Typical size: 60-80 MB depending on your app
- The script is written in pure JavaScript (cross-platform)
- Each platform generates its own executable
- Use the
-Vflag to include version in the filename
Windows: "The signature seems corrupted" warning
When building on Windows, you may see this warning during the injection step:
warning: The signature seems corrupted!This is completely normal and harmless!
Here's why it happens:
- Windows signs all
.exefiles with a digital signature for security - When
postjectinjects the SEA blob, it modifies the binary structure - This breaks the original Windows signature (but the file still works perfectly)
- The warning is just informational and can be safely ignored
The executable will work perfectly fine without the signature. If you want to sign it with a code signing certificate, you can use signtool from the Windows SDK (requires a valid certificate).
Injection takes 30-60 seconds
⏳ Important: The injection step (step 4/5) can take 30-60 seconds depending on your disk speed.
This is because postject needs to:
- Read the entire Node.js binary (50-80 MB)
- Inject the SEA blob into it
- Write the complete file back to disk
This is normal and expected. Just wait for the process to complete. Do not interrupt it during this step!
Automatic Bundling with Dependencies
When you have npm packages in your node_modules, node2exe automatically bundles them into the executable using esbuild. This works great for most packages!
npm install colors
npx node2exe
# This automatically bundles 'colors' into the executable⚠️ Important: Assets and Data Files
Some npm packages require external data files (like databases or configuration files). These cannot be automatically bundled into the executable because:
- SEA doesn't support file system access for bundled assets by default
- Data files are not code - esbuild bundler only handles JavaScript
- Path resolution fails - packages looking for files on disk won't find them in the executable
Examples of packages with data files:
geoip-lite- requires.datfiles- SQLite databases -
.dbfiles - Font files, images, config files
Solutions:
Use online APIs instead - Replace local data with API calls (recommended) ✅
// Instead of: const geoip = require('geoip-lite'); // Use: fetch('https://ip-api.com/json/' + ip)Use web services - Move data-heavy operations to cloud services
Manually add assets - Edit
sea-config.jsonto include assets (advanced, complex)
