Packaging Node.js code into cross platform executables

If you’re writing command line tools in Node.js, it can be hard to distribute them since users need to install Node.js in their machines before being able to use your tool. It would be a lot easier for users if we can package our app into a single executable file that they can download and run without installing anything extra.

We can use pkg to compile our code into a single executable file for multiple target platforms (Windows, Linux, Mac etc).

Let’s start with a simple example:

// index.js
console.log("hello world");

This file prints “hello world” and exits. We can package this by running:

$ npx pkg index.js

This by default builds executables for three platforms - Windows, Linux and Mac:

$ ls -1
index-linux
index-macos
index-win.exe
index.js

The target platforms can be customized by using the --targets flag.

I was curious how much space these take up:

$ ls -lh
total 183496
-rwxr-xr-x  1 sheshbabu  staff    33M Mar 31 01:40 index-linux
-rwxr-xr-x  1 sheshbabu  staff    34M Mar 31 01:40 index-macos
-rw-r--r--  1 sheshbabu  staff    22M Mar 31 01:40 index-win.exe
-rw-r--r--  1 sheshbabu  staff    28B Mar 31 00:46 index.js

22-34MB feels like a bit too much for something that just prints “hello world”. Looking around the internet, it seems we can use tools like upx to reduce the file size.