Building single binaries for your Node.js projects

 ⋅ 1 min read

nodejs-binary

A lot of programming languages and runtimes (like Go, Rust & C/C++) offer self-contained distributable binaries, and as someone that spends most of their time on Node.js, I've been quite jealous of them... until now.

js2bin aims to build single binaries for Node.js projects on Linux and macOS. Although similar projects like nexe and pkg exist, js2bin is slightly different (IMHO, better) in how it works; in the words of the author

They (nexe and pkg) both embed users application and other content by appending to the executable – while this method works, it can also trip malware scanners as the executable contains extraneous content.

How to use js2bin

To be able to use js2bin, you need to first bundle your Node.js application into a single JS file. You can try using webpack or rollup, but I found a much simpler solution in ncc.

ncc supports TypeScript out of the box too, so all you have to do to is run —

ncc build src/index.ts -o bundle

src/index.ts is your main entrypoint, and bundle is the output directory.

Once you have a single JS file, you can then run —

js2bin --cache --build --platform=darwin --platform=linux --platform=windows --app=bundle/index.js

This creates binaries for macOS, Linux and Windows using the bundled JS you created in the previous step.

🚩 Caveats

js2bin does not work with projects that have native modules. To quickly check if your project uses native modules, run —

find node_modules -type f -name "*.node"

Real-world example

I used js2bin to generate executables and a CD workflow to automatically attach them to releases on a hobby project of mine; here's the key pieces of interest —

  1. npm scripts
  2. GitHub Actions CD workflow
  3. Releases page with binaries as release attachments.