Skip to content

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

sh
napi artifacts [--options]
ts
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:

text
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:

yaml
- 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:

text
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:

text
.
├── 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:

  1. Splits the final dot-delimited suffix from the file name, such as linux-x64-gnu.
  2. Requires the remaining base name to equal napi.binaryName. A mismatched binary name is warned about and skipped.
  3. 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.
  4. 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.js
  • wasi-worker.mjs
  • wasi-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.

Last updated on
LongYinan