safebuild
v1.1.0
Published
A unified, safer installer/loader for Node.js native addons — prebuilt binaries first, node-gyp source builds as a verified fallback, with plain-English diagnostics instead of node-gyp's cryptic failures.
Maintainers
Readme
safebuild
A unified, safer installer/loader for Node.js native addons — prebuilt binaries first, node-gyp source builds as a verified fallback, with plain-English diagnostics instead of node-gyp's cryptic failures.
Why not just use node-gyp directly?
node-gyp itself isn't going anywhere — it's the only thing that actually drives Python + a C/C++ toolchain to compile a native addon, and safebuild still uses it under the hood for source builds. The pain is everything around it:
- Every
npm installof a native addon can trigger a full source compile unless the addon ships prebuilt binaries — and the ecosystem's answer to that (prebuild+prebuildify+node-gyp-build+prebuild-install) is four separate packages with overlapping conventions. - When a build does fail,
node-gypdumps pages of raw compiler/Python/npm output with no indication of what to actually do — "missing Python," "missing Visual Studio," and "no network access" all look like unreadable walls of text to someone who just rannpm install.
safebuild is one coherent package covering the same territory:
- Prebuilt binary first.
load(dir)looks forprebuilds/<platform>-<arch>[-musl]/node.napi.node(the same layoutprebuildifyalready uses, so existing prebuilds work unmodified) before ever touching a compiler. - Checksum-verified downloads. If a package configures a remote prebuild URL, safebuild downloads to a temp path, verifies its sha256, and only then atomically moves it into place — a failed or tampered download never leaves a usable binary behind.
node-gypas a clearly-labeled fallback, not the default path — only invoked when no local or remote prebuild is available.- Plain-English build diagnostics. On a failed source build, safebuild pattern-matches the output against common failure classes (missing Python, missing Visual Studio, missing Xcode CLT, missing make/gcc, network failure, permission errors, a broken
binding.gyp) and prints one clear cause + remediation instead of the raw log alone. - N-API only, on purpose. safebuild's prebuilt-binary convention targets N-API addons specifically — one binary per platform/arch that's ABI-stable across Node versions, instead of the combinatorial explosion of per-Node-ABI binaries that made prebuilt distribution painful in the first place.
Install
npm install safebuildUsage
As the addon's install step
In the native addon's own package.json:
{
"scripts": { "install": "safebuild install" },
"safebuild": {
"prebuildUrl": "https://github.com/you/addon/releases/download/v{version}/{platform}-{arch}{libc}.node",
"checksums": {
"linux-x64": "…sha256…",
"darwin-arm64": "…sha256…"
}
}
}safebuild install, in order:
- Checks for a bundled prebuild at
prebuilds/<platform>-<arch>/node.napi.node— if present, done, no network, no compiler. - If a
safebuild.prebuildUrl+ matching checksum is configured, downloads and verifies it. - Otherwise runs
node-gyp rebuild. On failure, prints a diagnosis instead of just the raw output.
At runtime, in the addon's entry point
const { load } = require("safebuild");
module.exports = load(__dirname);load() tries the prebuild, then a local build/Release/*.node (node-gyp's own output layout), and throws a SafeBuildError listing every path it tried if neither exists.
API
load(rootDir, options?)— resolves and requires the native addoncurrentTarget(),targetDirName(target),detectLibc()— platform/target-triple helpers (glibc vs musl aware)locatePrebuild(rootDir, target?),prebuildPath(rootDir, target?)downloadPrebuild({ url, sha256, destPath })— checksum-verified fetch using only Node built-ins, no HTTP dependencyrunNodeGyp({ cwd, args? })— spawns safebuild's ownnode-gypdependency, captures outputdiagnose(output)/formatDiagnosis(diagnosis)— turn rawnode-gypoutput into a{ category, summary, remediation }SafeBuildError/isSafeBuildError(err)— codes:BINARY_NOT_FOUND,CHECKSUM_MISMATCH,DOWNLOAD_FAILED,BUILD_FAILED,INVALID_MANIFEST
What's out of scope for v1.1.0
- Non-N-API (per-ABI-version) prebuilt binaries — use N-API for new addons; safebuild's
node-gypfallback still builds whateverbinding.gypspecifies either way - Windows/macOS-specific diagnosis signatures are pattern-based on common
node-gypoutput and not exhaustively tested on those platforms (this package was built and tested on Linux) - A
create/initscaffolding command for new addons
License
MIT
