Skip to content

NAPI Config

Put the configuration under the napi key in package.json:

package.json
json
{
  "name": "@scope/addon",
  "napi": {
    "binaryName": "addon",
    "targets": ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin"]
  }
}

Commands that expose --config-path can instead read a standalone JSON file. When both sources are present, the standalone config takes precedence. All user-supplied fields are optional.

Schema

ts
{
  napi?: {
    binaryName?: string
    targets?: string[]
    packageName?: string
    npmClient?: string
    constEnum?: boolean
    runtimeStringEnum?: boolean
    dtsHeader?: string
    dtsHeaderFile?: string
    wasm?: {
      initialMemory?: number
      maximumMemory?: number
      browser?: {
        fs?: boolean
        asyncInit?: boolean
        buffer?: boolean
        errorEvent?: boolean
      }
    }
  }
}

Fields and effective defaults

Field Default Description
binaryName index Base name of generated native and WASI files. A platform build produces a name such as index.win32-x64-msvc.node.
targets [] Target triples the project packages and publishes. This is not a multi-target build command.
packageName root package.json name Package name used by generated loaders and per-platform package names. Override it when the JavaScript package name differs from the root package metadata; see Build: JS package name.
npmClient npm Command used for npm operations such as publishing each platform package.
constEnum true Generate TypeScript const enum declarations. The effective type-generation default is true when neither config nor CLI overrides it.
runtimeStringEnum false With constEnum: false, emit #[napi(string_enum)] as a runtime enum instead of a type-only string union. It has no effect while constEnum is true.
dtsHeader undefined String used as the header of the generated declaration file. It replaces the default header entirely; see Declaration file header.
dtsHeaderFile undefined Path, relative to the command's working directory, to a file whose content is used as the declaration file header. It takes precedence over dtsHeader.
wasm.initialMemory 4000 pages Initial shared WebAssembly memory, approximately 250 MiB.
wasm.maximumMemory 65536 pages Maximum shared WebAssembly memory, 4 GiB.
wasm.browser.fs false Include the in-memory filesystem and filesystem proxy in browser WASI bindings.
wasm.browser.asyncInit false Use emnapi's asynchronous module-instantiation path for the browser binding.
wasm.browser.buffer false Import Buffer and inject it into the emnapi context used by the browser binding.
wasm.browser.errorEvent false Forward worker failures to a browser napi-rs-worker-error CustomEvent, including captured worker error output.

One WebAssembly memory page is 64 KiB. The memory settings are written into the generated Node and browser WASI loaders; they are not Cargo memory limits.

INFO

runtimeStringEnum: true requires constEnum: false. The equivalent build flags are --runtime-string-enum --no-const-enum.

Declaration file header

When NAPI-RS generates index.d.ts, it starts the file with a default header:

typescript
/* auto-generated by NAPI-RS */
/* eslint-disable */

You can replace this header with your own TypeScript types, imports, license comments, or lint directives. A custom header replaces the default header entirely; include the auto-generated comment and the eslint directive in your own header if you want to keep them.

There are three ways to set the header, plus one way to disable it:

Method Location Best for
dtsHeaderFile napi config Complex headers with imports
dtsHeader napi config Simple single-line additions
--dts-header CLI flag of napi build CI/CD overrides
--no-dts-header CLI flag of napi build Disable the header entirely

When several of them are set, NAPI-RS resolves the header in this order:

Priority Source Description
1 Header file dtsHeaderFile (or the programmatic dtsHeaderFile option). A header file always wins over inline header text.
2 --dts-header (CLI) Overrides the inline dtsHeader config value, but not a header file.
3 dtsHeader (config) Inline string in the napi config.
4 Default header Used when nothing else is specified.

--no-dts-header skips header resolution and generates the .d.ts without any header.

For example, with a complex header in dts-header.d.ts:

dts-header.d.ts
typescript
/* auto-generated by NAPI-RS */
/* eslint-disable */

import type { ReadableStream } from 'node:stream/web'

type MaybePromise<T> = T | Promise<T>
package.json
json
{
  "napi": {
    "dtsHeaderFile": "./dts-header.d.ts"
  }
}

See Types overwrite for the attribute-level TypeScript overrides (ts_args_type, ts_return_type, and friends), which change individual declarations rather than the file header.

What targets controls

targets drives packaging:

  • napi create-npm-dirs creates one npm directory per target.
  • napi artifacts maps built files into those directories.
  • napi pre-publish versions and publishes those packages.
  • A WASI target enables generation of <binaryName>.wasi.cjs and the related browser and worker files.

Setting targets does not make napi build compile each entry. Every build invocation produces one target selected by --target, CARGO_BUILD_TARGET, or the host default. Likewise, the cross-compilation flags (--use-napi-cross, --cross-compile, and --use-cross) have no config equivalent.

The target list also does not create arbitrary CI jobs. napi new filters the jobs already present in its selected template. If you add another accepted target, add its build job and verify its runtime separately. See Support and compatibility and Cross build.

Deprecated v2 fields

The CLI still reads these fields for compatibility, but new projects should not use them:

Deprecated Replacement
napi.name napi.binaryName
napi.triples.defaults and napi.triples.additional napi.targets

The old nested napi.package.name field is not read by the v3 config normalizer. Move that value explicitly to napi.packageName.

What is a target triple?

See Rust platform support and LLVM cross-compilation. A target triple describes the architecture, vendor, operating system, and ABI of the artifact, for example:

text
x86_64-unknown-linux-gnu
└─ arch  └ vendor └ system └ ABI

Once you know which triples you intend to ship, use Cross build to choose and verify the build mechanism for each one.

Last updated on
LongYinan