build.zig (addLib)
Contents
napi.addLib is the only build.zig API you need. It registers your addon as a Zig artifact, applies the right linker flags for each OS, sets up the .d.ts install, and (with -Dnpm=true) builds the cross-compile graph and generates the npm package skeleton.
You can call it more than once in the same build.zig to ship multiple addons from one repo. Each call writes its own zig-out/lib/<name>.node and its own npm/<name>/ tree, and the CLI (napikit build, napikit build --release, napikit bump, napikit publish, napikit npm-init) picks up every one. Give each addon its own .scope; per-platform binding package names are derived from the scope, so two addons sharing a scope would publish under the same binding names.
LibOptions
Import
Pass via .imports = &.{ .{ .name = "parser", .module = parser } }. See Project layout: where to put your code.
NpmConfig
.repository
npm requires a repository field on every published package for provenance to verify against the source tree, otherwise napikit publish fails in CI with "package must specify a repository". An addon ships as the main package plus one binding per platform (twelve package.json files with the default platform set), and setting .repository once in build.zig writes the field into every one of them on each release build, so you never have to keep them in sync by hand.
Two accepted forms:
The shorthand expands to git+https://github.com/owner/repo.git. Anything starting with http://, https://, git+, git@, or ssh:// is passed through unchanged so non-GitHub hosts work too. If .repository is empty, no field is emitted and any value already in the existing package.json is preserved.
Dts
See TypeScript declarations for what each mode produces.
With .none, the generated main package has no types field and does not list or contain index.d.ts. If a previously typed release package switches to .none, the release reconciler removes that build-owned declaration without deleting unrelated files.
Platform
A tagged enum of every supported (OS, architecture, libc) tuple. Used in .npm.platforms. Defaults are exposed as Platform.defaults:
Override the default set with:
What addLib does
- Creates a Zig module from
.rootand adds thenapiimport. - Adds any
.importsto the module. - Builds a dynamic library named
<name>.node. - Configures linker flags per OS:
- macOS:
linker_allow_shlib_undefined = true. - Linux/FreeBSD: links libc, restricts exports to N-API entry points via
exports.ld. - Windows: generates an import library from
node_api.defso the linker resolves N-API symbols against the host.exeat runtime.
- macOS:
- Drops red zone, unwind tables, and unreferenced sections (smaller binaries, no surprise symbols).
- If
.npmis set, installs the.d.tsnext to the binary in the right format. - If both
.npmis set and-Dnpm=trueis passed, generates the full cross-compile graph and thenpm/package tree.
napikit build --release is exactly zig build -Dnpm=true -Doptimize=ReleaseFast with the per-platform target loop applied to every entry in .npm.platforms. You can run it directly if you prefer.
Two build options narrow that loop, set for you by the matching CLI flags:
Under -Dnpm-host the main package.json still lists every platform in optionalDependencies, so a later full build stays complete. See Building a subset.