Skip to content

Type Mapping (JS ↔ Rust)

Fresh 🌱

How JavaScript types correspond to Neon's Js* handle types and the Rust values you build them from or read them into.

Primitives

JavaScriptNeon handle typeBuild from RustRead into Rust
numberJsNumbercx.number(x) where x: f64-compatible.value(&mut cx)f64
stringJsStringcx.string(&s).value(&mut cx)String
booleanJsBooleancx.boolean(b).value(&mut cx)bool
nullJsNullcx.null()-
undefinedJsUndefinedcx.undefined()-

Objects & collections

JavaScriptNeon handle typeNotes
{} objectJsObjectget/set via the Object trait
[] arrayJsArraycx.empty_array(); len, to_vec, indexed get/set
BufferJsBuffercx.buffer(n)?
ArrayBufferJsArrayBuffercx.array_buffer(n)?
typed arrayJsTypedArray<T>as_slice(&cx) / as_mut_slice(&lock) for zero-copy access
DateJsDaterequires a sufficient napi-N feature

Functions & special

JavaScriptNeon handle typeNotes
functionJsFunctionbind(), call_with(), construct_with()
PromiseJsPromisefrom cx.promise() or cx.task(...).promise(...)
any valueJsValuethe supertype; use when you do not need to narrow the type
boxed Rust dataJsBox<T>opaque to JS; T: Finalize

The umbrella types

TypeMeaning
Handle<'a, T>a safe, lifetime-tracked reference to a JS value of type T
JsResult<'a, T>Result<Handle<'a, T>, Throw> - a function that may throw
NeonResult<T>Result<T, Throw> - used by #[neon::main] and non-handle returns
Root<T>a persistent reference that survives across threads/async

Argument extraction (with #[neon::export])

When using the macro, plain Rust types convert automatically:

Rust parameter typeAccepts JavaScript
f64number
Stringstring
boolboolean
Option<T>T or a missing/undefined trailing argument
(A, B, ...) via cx.args()a positional argument list

Narrow only as much as you need

Read an argument as JsValue when you just need to pass it through, or as a specific Js* type when you want Neon to type-check it for you (and throw a TypeError if it does not match).