Artifacts
napi artifacts recursively finds built .node and .wasm files, validates
their binary names and target suffixes, and copies them into the matching
per-platform npm packages. Native files are also copied to the root package
directory so the generated loader can resolve a local binding.
Usage
napi artifacts [--options]
import { NapiCli } from '@napi-rs/cli'
await new NapiCli().artifacts({
outputDir: 'artifacts',
npmDir: 'npm',
})
Options
| Option | CLI syntax | Type | Required | Default | Description |
|---|---|---|---|---|---|
cwd |
--cwd |
string |
No | process.cwd() |
Base directory for config, package, artifact-download, npm-package, and build-output paths. |
configPath |
--config-path,-c |
string |
No | Standalone napi config JSON file. | |
packageJsonPath |
--package-json-path |
string |
No | package.json |
Root package containing the napi config. |
outputDir |
--output-dir,-o,-d |
string |
No | ./artifacts |
Directory recursively searched for downloaded .node and .wasm files. This corresponds to the artifact-download path, not npm/. |
npmDir |
--npm-dir |
string |
No | npm |
Directory containing the generated per-platform packages. |
buildOutputDir |
--build-output-dir |
string |
No | cwd |
Directory containing generated WASI JavaScript and worker files. Relative paths resolve from --cwd. |
There is no --dist option. Use --output-dir for downloaded build artifacts
and --npm-dir for platform package destinations.
CI workflow
Each build job should upload files named with the configured binary name and target ABI, for example:
cool.darwin-arm64.node
cool.linux-x64-gnu.node
cool.win32-x64-msvc.node
cool.wasm32-wasi.wasm
In the collection job, create the package directories, download all artifacts, then collect them:
- name: Create platform packages
run: yarn napi create-npm-dirs
- name: Download all build artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
- name: Move artifacts into packages
run: yarn napi artifacts --output-dir artifacts --npm-dir npm
actions/download-artifact normally creates one nested directory per uploaded
artifact. The CLI searches recursively, so both of these layouts work:
artifacts/
├── bindings-aarch64-apple-darwin/
│ └── cool.darwin-arm64.node
├── bindings-x86_64-unknown-linux-gnu/
│ └── cool.linux-x64-gnu.node
└── bindings-x86_64-pc-windows-msvc/
└── cool.win32-x64-msvc.node
After collection:
.
├── cool.darwin-arm64.node
├── cool.linux-x64-gnu.node
├── cool.win32-x64-msvc.node
└── npm/
├── darwin-arm64/cool.darwin-arm64.node
├── linux-x64-gnu/cool.linux-x64-gnu.node
└── win32-x64-msvc/cool.win32-x64-msvc.node
Matching rules
For each discovered file, the CLI:
- Splits the final dot-delimited suffix from the file name, such as
linux-x64-gnu. - Requires the remaining base name to equal
napi.binaryName. A mismatched binary name is warned about and skipped. - Finds the configured target package whose directory matches that platform suffix. A file with no target package causes the command to fail, except source binaries that are intentionally combined into a configured universal binary.
- Writes the file into that target package and the root package directory.
WARNING
The command trusts the suffix in the file name. It does not inspect the native binary to prove its architecture, libc, minimum OS, or Node-API level. Test every artifact on the runtime it claims to support before publishing.
WASI artifacts
When napi.targets contains a WASI target, napi artifacts also copies the
generated support files into npm/wasm32-wasi:
<binaryName>.wasi.cjs<binaryName>.wasi-browser.jswasi-worker.mjswasi-worker-browser.mjs
By default these files are read from --cwd. Pass --build-output-dir when the
WASI build wrote them elsewhere; a relative value is resolved from --cwd.
The downloaded .wasm file is still discovered under --output-dir.
After collecting and verifying all targets, napi pre-publish
versions and publishes the platform packages. napi pre-publish does not copy
missing artifacts for you.