Hey Node devs, jealous of Go devs for being able to create single binaries without any dependencies?
Now you can do it too! With pkg - a binary compiler for NodeJS!

pkg - from NodeJS to binary

I recently developed a NodeJS script that automatically consumes SQS messages when an EC2 instance is initiated.
My most major issue has been the dependencies - NodeJS installation was often slow, and would sometimes fail or timeout.
On top of that, I had to also install the AWS SDK in order to get the SQS messages.
The entire thing was too much of a delay for my User Data script to handle.

Side Note: User Data is a script that executes when an EC2 instance is initialized. Very useful for pulling Docker images or running init scripts.

After an evening of debugging, I started thinking - this would be a whole lot easier with Go, as I would just have a single binary file and zero dependencies to install.
The issue was that converting my entire script to Go would've required much more time, and would likely create new issues (as AWS SDK varies between the languages, not to mention I'm much more experienced with NodeJS compared to Go).
I then thought that within the infinite universe of NPM there must be a tool that packages binaries out of NodeJS scripts, or at least somehow bundles the NodeJS runtime together with my script.

pkg to the rescue!

pkg allows you to bundle your NodeJS scripts into a single binary.
No more dependencies, no more node_modules/, package.json, npm install...
Simply download the single executable and... well... Execute!

I have successfully tested the following with pkg:
  • NodeJS environment (obviously) - includes Node8, Node6, and Node4 (9 is not supported yet)
  • Operating System - includes linux, mac, and windows
  • NPM Libraries (aws-sdk in my case) - works without any configuration
  • Environment Variables - works without any configuration
  • Spawning Child Processes - works without any configuration
  • Async/Await - works without any configuration

Install pkg

npm install -g pkg
Tip: it also works if you install it locally, you would simply have to run:
./node_modules/.bin/pkg
instead of just pkg

Run pkg

pkg --targets node8-linux server.js -o server-linux
The command above simply bundles server.js into a linux binary named server-linux



Until next time!