Functions
Function wrappers represent JavaScript callables with Zig types.
Function
napi.Function(comptime Args: type, comptime Return: type)
Use Function when Zig needs to call a JavaScript function or expose a Zig function manually.
const Callback = napi.Function(.{ i32, i32 }, i32);
pub fn call(callback: Callback) !i32 {
return callback.Call(.{ 1, 2 });
}
| Method | Use |
|---|---|
from_raw(env, raw) |
Wrap an existing JavaScript function. |
New(env, name, value) |
Create a JavaScript function from a Zig function. |
Call(args) |
Call the JavaScript function and convert the result. |
CreateRef() |
Create Reference(Function(Args, Return)). |
Args may be a tuple type for multiple arguments, a non-tuple type for one argument, or an empty struct for no arguments.
Function Exports
When a pub fn is exported through NODE_API_MODULE, the wrapper:
- Injects
napi.Envwhen it is the first parameter. - Converts JavaScript arguments into Zig parameter types.
- Calls the Zig function.
- Converts the return value into JavaScript.
- Maps Zig errors and
napi.Result(T).Errinto JavaScript exceptions.
If the returned payload is an async descriptor, the function returns a Promise and schedules the async operation.
FunctionRef
napi.FunctionRef(comptime Args: type, comptime Return: type)
FunctionRef is a convenience alias for Reference(Function(Args, Return)).
Use it when the native side needs to hold a JavaScript function beyond the current call.
CallbackInfo
napi.CallbackInfo
CallbackInfo is the low-level callback context. It reads callback arguments with an inline buffer for up to eight arguments and heap storage for larger calls.
| Method | Use |
|---|---|
from_raw(env, info) |
Read callback information. |
deinit() |
Free heap-backed argument storage. |
Env() |
Return napi.Env. |
Get(index) |
Return argument as NapiValue. |
Len() |
Argument count. |
ArgsRaw() |
Raw napi_value slice. |
ArgRaw(index) |
One raw argument. |
This() |
Raw this value. |
Most exported functions should use typed Zig parameters instead. CallbackInfo is useful for variadic or dynamic APIs.
ThreadSafeFunction
napi.ThreadSafeFunction(
comptime Args: type,
comptime Return: type,
comptime ThreadSafeFunctionCalleeHandled: anytype,
comptime MaxQueueSize: anytype,
)
Use ThreadSafeFunction to call a JavaScript function from native threads. It requires Node-API v4 or newer.
ThreadSafeFunctionCalleeHandled = true makes the JavaScript callback receive an error-first argument: (err, ...args) => void.
The error-first convention is strict: a successful call passes null in the
error slot followed by the queued arguments, and a failed call passes the error
alone. The error call has a single argument, so a callback written as
(err, value) => void sees value === undefined for a failure; the remaining
argument slots are omitted rather than filled with placeholder values.
Without ThreadSafeFunctionCalleeHandled there is no error slot. Err() still
runs the callback, with the argument slots passed as undefined; the error
itself cannot be delivered to JavaScript.
const callback = (err, first, second) => {
if (err) {
// The failure call passed exactly one argument.
return;
}
// A success passes the queued arguments after `null`.
};
| Method | Use |
|---|---|
from_raw(env, raw) |
Create a TSFN from a JavaScript function. |
acquire() |
Increment active thread usage. |
release(mode) |
Release usage or abort release. |
abort() |
Stop future calls. |
ref() / unref() |
Control event-loop lifetime. |
Ok(args, mode) |
Send a successful call. |
Err(error, mode) |
Send an error call. |
deinit() |
Destroy the wrapper allocation. |
Queueing and payload ownership
Ok(args, mode) and Err(error, mode) take ownership of their payload on every
path, including a full queue, a closing TSFN and a failed allocation: a returned
error means "not queued", never "you still own the payload". Both report
allocation failure as a Zig error instead of aborting the process.
Err copies the message and code of the error it is given. The text of a
napi.Error is borrowed, so the caller's buffer may be reused as soon as the
call returns; what JavaScript finally sees is the copy. The copy is released
when the call is delivered, when it is rejected, and when the queue is drained
during environment shutdown. If the copy itself cannot be allocated, the
delivered error degrades to a fixed native error instead of falling back to the
borrowed bytes. If the error object cannot be built at all, the failure call is
not dispatched (the payload is still released) - a failure is never delivered as
a successful call.
Queued calls keep working while the callback throws: the pending JavaScript
exception is left to the runtime, and later calls are still dispatched. Whether
that exception reaches uncaughtException depends on Node's
--force-node-api-uncaught-exceptions-policy option, not on this wrapper.
TSFN parameters and conversion rollback
A *napi.ThreadSafeFunction(...) parameter promotes the JavaScript function it
received. The promotion is part of the argument conversion, so a call that is
rejected before the native body runs - for example because a later argument has
the wrong type - releases it again. Once the body runs, the TSFN belongs to the
body: it is usually handed to another thread, and nothing aborts it when the
exported function returns. The body remains responsible for the final
release()/abort().
TSFN Modes
napi.ThreadSafeFunctionMode.NonBlocking
napi.ThreadSafeFunctionMode.Blocking
napi.ThreadSafeFunctionReleaseMode.Release
napi.ThreadSafeFunctionReleaseMode.Abort
NonBlocking may fail with QueueFull when the queue is full. Blocking waits for room. Release mode controls whether the TSFN drains normally or aborts queued work.