Distributing executable binaries in npm package
Let’s say you need to distribute binary in npm. I’m not talking about node extensions (node-gyp, napi, etc.). I’m talking about standalone executables, like CLI applications.
We have options. How to distribute binary:
- host executables on some server, for example, GitHub releases, and download appropriate (e.g. for given OS and architecture) binary on installation
- put all executables (for all OSs and architectures) in one npm package
- create sub-packages with binary for each OS and architecture and one “root” npm package which would list all sub-packages as optional dependencies
How to run the binary:
- Use JS wrapper which would call actual executable with
exec
,spawn
, etc. - On installation figure out where Node puts binaries and overwrite it with your binary from the package
- Use JS script to call node binding (
*.node
) or WASM
Tools and blog posts:
name | distribution | execution |
---|---|---|
binary-install | 1 | 1 (spawnSync ) |
binwrap | 1 | 1 (spawn ) |
bin-wrapper | 1 | 1 (spawn , …) |
prebuild-install | 1 | 3 |
blog.xendit.enginee | 2 | 2 |
hspak.dev | 2 | 2 |
prebuildify | 2 | 3 |
blog.orhun.dev | 3 | 1 (spawnSync ) |
napi-rs | 3 | 3 |
Example projects:
name | distribution | execution |
---|---|---|
odiff | 2 | 2 |
@astrojs/compiler | 2 (WASM) | 3 |
esbuild | 3 | 1 (execFileSync ) |
biome | 3 | 1 (spawnSync ) |
Turborepo | 3 | 1 (execFileSync ) |
lightningcss | 3 | 3 |
Read more: Distributing CSS in npm package, Server-side UI Components