Type conversion
Contents
- Zig to JS
- JS to Zig
- Structs
- Enums
- Tuples
- Optionals and null
- Custom conversion
- Buffers and typed arrays
The bridge auto-converts every supported Zig type to and from a JS value. The two endpoints are:
env.toJs(value)for Zig to JS. Used implicitly on every return value, callback argument, and field assignment.val.to(env, T)for JS to Zig. Used implicitly on every JS argument that is bound to a typed parameter.
You usually never call them directly. They are listed here so you know what is happening underneath, and so you can call them yourself when working with napi.Val directly.
Zig to JS
JS to Zig
Type mismatches throw a JS TypeError with the actual JS type:
A BigInt that does not fit the target Zig int throws RangeError: bigint out of range for .... To handle lossy values yourself instead of erroring, take a napi.Val parameter and call getBigIntI64 / getBigIntU64.
Structs
Struct fields are matched by camelCase name. Zig default values are used when the JS object omits a property:
This makes it cheap to add a field: bump the Zig struct, give it a default, no JS callers break.
Enums
Enums map to and from strings.
Both the snake_case and camelCase form of every variant is accepted on the way in. The way out is always camelCase.
Tuples
A Zig anonymous tuple maps to a JS array, and vice versa.
Optionals and null
?T is T | null on the JS side. null on the Zig side becomes null in JS. undefined on the JS side is treated as null when converting to ?T.
Custom conversion
For types the converter cannot handle (unions, opaque handles, tagged shapes), define toJs and fromJs on the type. They take priority over the default field-by-field walk.
Both methods are looked up by name. Defining only one is fine; the auto-converter handles the other direction.
Buffers and typed arrays
Buffers are intentionally not in the auto-conversion table. The converter cannot know whether you want a copy, a borrowed slice, or a typed array view. Build them explicitly:
env.createBuffer(len)returns{ .val, .data }(a JS Buffer plus a writable[]u8).env.createArrayBuffer(len)does the same forArrayBuffer.val.getBufferData(env)returns a[]u8into the existing memory.
See the Env reference for the full list.