The low-level TypeScript binding for the MapLibre Native C API.
The desktop binding supports Linux with glibc on Node.js, Bun, and Deno,
Linux with musl on Node.js and Bun, and macOS and Windows on all three runtimes.
The GNU RISC-V, LoongArch64, and FreeBSD x64 addons support Node.js.
Windows backend packages use MSVC. To use a MinGW native host on x64,
install @maplibre/native-ffi-opengl-mingw or
@maplibre/native-ffi-vulkan-mingw instead of the ordinary backend package.
Native handles shared with the host must come from the same C library DLL
that the addon loads.
Every callback reaches the realm's event loop after the native call that
raised it has returned, so native code answers each synchronous decision
itself. A provider or transform request arrives as an owner that the host
answers later.
Native code in the host can supply a wake or a queue lock as a native
registration: Wake.native({ callback, userData, releaseUserData }) or
QueueLock.native({ lock, unlock, userData, releaseUserData }), with each
function pointer and the context as a bigint address. Native code calls a
native wake directly, without a post to the realm. A queue lock has only this
form, because native code relies on the lock being held when its callback
returns. The first call that carries a native registration consumes it, and a
later call throws a MaplibreError with the invalid-state status. Native code
releases the context of a call that it accepts, and the binding calls the
release for any other call.
A pending binding Promise keeps the process alive, and a callback
registration or a wake does not. To wait for a callback, call the wake
member of an AwaitableWake from it and await next().
Every 64-bit C integer, such as a generation, a timestamp, or a 64-bit mask,
is a bigint, so it keeps its full range. JSON.stringify throws a
TypeError on a bigint unless a replacer converts it.
A JSON value is any value that JSON.stringify takes, typed unknown, so
setStyleLayerProperty("roads", "line-color", "red") needs no inner quotes.
In a parameter or a record member, undefined is absent, which native code
reads as empty, and null is JSON null, such as the null that restores a
layer property's default. A value that JSON.stringify rejects throws its
error before the call reaches native code, and one that it skips, such as a
function, throws a TypeError. Returned JSON is the value that JSON.parse
reads, and absent JSON is undefined. JSON.parse reads every number as a
number, so an integer above 2^53, such as some feature IDs, loses
precision.
A realm runs on one thread, so it can drive a caller-driven render session:
make its context current on the JavaScript thread and call
serviceDriverWork() when the driver-work wake arrives. A realm loads one
copy of the binding.
The low-level TypeScript binding for the MapLibre Native C API.
The desktop binding supports Linux with glibc on Node.js, Bun, and Deno, Linux with musl on Node.js and Bun, and macOS and Windows on all three runtimes. The GNU RISC-V, LoongArch64, and FreeBSD x64 addons support Node.js.
Windows backend packages use MSVC. To use a MinGW native host on x64, install
@maplibre/native-ffi-opengl-mingwor@maplibre/native-ffi-vulkan-mingwinstead of the ordinary backend package. Native handles shared with the host must come from the same C library DLL that the addon loads.Every callback reaches the realm's event loop after the native call that raised it has returned, so native code answers each synchronous decision itself. A provider or transform request arrives as an owner that the host answers later.
Native code in the host can supply a wake or a queue lock as a native registration:
Wake.native({ callback, userData, releaseUserData })orQueueLock.native({ lock, unlock, userData, releaseUserData }), with each function pointer and the context as abigintaddress. Native code calls a native wake directly, without a post to the realm. A queue lock has only this form, because native code relies on the lock being held when its callback returns. The first call that carries a native registration consumes it, and a later call throws aMaplibreErrorwith the invalid-state status. Native code releases the context of a call that it accepts, and the binding calls the release for any other call.A pending binding Promise keeps the process alive, and a callback registration or a wake does not. To wait for a callback, call the
wakemember of an AwaitableWake from it and awaitnext().Every 64-bit C integer, such as a generation, a timestamp, or a 64-bit mask, is a
bigint, so it keeps its full range.JSON.stringifythrows aTypeErroron abigintunless a replacer converts it.A JSON value is any value that
JSON.stringifytakes, typedunknown, sosetStyleLayerProperty("roads", "line-color", "red")needs no inner quotes. In a parameter or a record member,undefinedis absent, which native code reads as empty, andnullis JSON null, such as the null that restores a layer property's default. A value thatJSON.stringifyrejects throws its error before the call reaches native code, and one that it skips, such as a function, throws aTypeError. Returned JSON is the value thatJSON.parsereads, and absent JSON isundefined.JSON.parsereads every number as anumber, so an integer above 2^53, such as some feature IDs, loses precision.A realm runs on one thread, so it can drive a caller-driven render session: make its context current on the JavaScript thread and call
serviceDriverWork()when the driver-work wake arrives. A realm loads one copy of the binding.