Slim down your binaries
Internally we develop our own tools, that we use as CLI. To make it easier to distribute and use them, we create standalone binaries. But often the files are huge.
So let's see how we can make them smaller without losing any functionality.
In our case, these tools are often either written in JavaScript or TypeScript. For creating the standalone binaries (to use them in Docker containers for example) we use pkg by Vercel.
But the resulting files are quite big, so I was looking for ways, to get them smaller.
The command that we use, is simple:
pkg . --targets node16-linux --output sync
With this code, we get a binary sync
, that we can drop into our containers.
The size of the generated file is 51 MB.
In the documentation of pkg we can find a --compression
setting, which supports Brotli and gzip.
-C, --compress [default=None] compression algorithm = Brotli or GZip
...
Compression
Pass --compress Brotli or --compress GZip to pkg to compress further the content of the files store in the executable.
This option can reduce the size of the embedded file system by up to 60%.
The startup time of the application might be reduced slightly.
-C can be used as a shortcut for --compress .
In most cases Brotli should provide smaller results than gzip, so let's try this.
The new command with Brotli compression:
pkg . --targets node16-linux --output sync --compress Brotli
Now we should have a smaller file. The size of the generated file with Brotly compression is 43 MB.
So that saved a few Megabytes. Not that much, but better than nothing.
But are there solutions to get even smaller binaries? Yes, there are established tools for compressing binaries.
Many might have already heard of UPX, which is often used. We tested that and by default, the Brotli compressed file did not get much smaller (around 41 Megabytes), when we tried to compress it with UPX.
So we tried another tool, called gzexe, which is part of the gzip package and also relies on that to decompress the generated files.
pkg . --targets node16-linux --output sync --compress Brotli && gzexe sync
The result was great. The new file is only 18 MB in size.
So with these simple steps, we drastically decreased the filesize from 51 to 18 Megabytes.
original size: 51M
brotli compressed: 43M
brotli compressed + gzexe: 18M
The same result can be achieved with UPX, but that took a bit longer compared to gzexe. Also in our case we already had gzip installed, so gzexe could be directly used without installing any extra software packages.
With this knowledge, you can easily compress your binaries. Your actual results may vary, so you should try to find the right compression settings and tools.