Install
Choose a render backend first. Prefer Metal for Apple platforms, OpenGL for emulators and virtual machines, and Vulkan for other platforms. Then install the C library, a binding for your language, or both. Each section covers its tagged releases, where they exist, and its snapshot channel.
C library
Section titled “C library”Download maplibre-native-c-<preset>.tar.gz for the target from the
latest release
and unpack it. The archive root is the install prefix. The
snapshot release
carries the same assets built from main under a fixed tag, so its download
URLs stay stable.
A preset name has the form <platform>-<arch>-<backend>, as in
macos-arm64-metal or linux-x64-vulkan. OpenGL presets name their context
provider in place of the backend: egl, wgl, or webgl.
Platforms gives the provider for each platform.
On Windows, add <prefix>/bin to PATH or copy maplibre-native-c.dll beside
your executable, because a prefix carries no loader path there. Linux and macOS
builds record an rpath into the prefix that they built against.
Export PKG_CONFIG_PATH to build against the prefix:
export PKG_CONFIG_PATH=<prefix>/share/pkgconfigcc -std=c23 main.c $(pkg-config --cflags --libs maplibre-native-c) -o mainTo build a prefix yourself, see the development overview.
Bindings
Section titled “Bindings”Each binding wraps the C library in one language. Most carry or download the C library, and the sections that need an installed prefix say so.
Kotlin
Section titled “Kotlin”Add Maven Central, the binding, and the runtime for your backend. The runtime carries the native library for every ABI.
repositories { mavenCentral()}
dependencies { implementation("org.maplibre.nativeffi:maplibre-native-ffi:0.202608.0") implementation("org.maplibre.nativeffi:maplibre-native-ffi-runtime-vulkan:0.202608.0")}Take one runtime module:
org.maplibre.nativeffi:maplibre-native-ffi-runtime-openglorg.maplibre.nativeffi:maplibre-native-ffi-runtime-metalorg.maplibre.nativeffi:maplibre-native-ffi-runtime-vulkan
On Android, initialize platform services before you create a runtime, as Android describes.
For the snapshot channel, add the Maven snapshot repository and take the snapshot version of both modules. The runtime modules and Android initialization match the release.
repositories { maven("https://central.sonatype.com/repository/maven-snapshots/") { content { includeGroup("org.maplibre.nativeffi") } } mavenCentral()}
dependencies { implementation("org.maplibre.nativeffi:maplibre-native-ffi:0.1.0-SNAPSHOT") implementation("org.maplibre.nativeffi:maplibre-native-ffi-runtime-vulkan:0.1.0-SNAPSHOT")}Add the snapshot feed, then the binding and the runtime for your backend.
<configuration> <packageSources> <add key="maplibre-snapshots" value="https://maplibre.github.io/maplibre-native-ffi/nuget/index.json" /> </packageSources></configuration><ItemGroup> <PackageReference Include="Maplibre.NativeFfi" /> <PackageReference Include="Maplibre.NativeFfi.Runtime.Vulkan" /></ItemGroup>Take one runtime package:
Maplibre.NativeFfi.Runtime.OpenGLMaplibre.NativeFfi.Runtime.MetalMaplibre.NativeFfi.Runtime.Vulkan
Depend on the package from Git. The build hook downloads a native artifact for your target when you build.
dependencies: maplibre_native_ffi: git: url: https://github.com/maplibre/maplibre-native-ffi path: bindings/dartThe hook chooses the default backend from the target. Name a different one in your application’s pubspec to override that.
hooks: user_defines: maplibre_native_ffi: backend: vulkanThe backends are opengl, metal, and vulkan.
Write an install prefix into .dart_tool/maplibre_native_install_dir to use
your own build instead. A pinned Git revision keeps the Dart code fixed, and the
hook still resolves the current snapshot for a build that has no artifact
cached. Point the hook at your own prefix when you need a fixed native library.
go get github.com/maplibre/maplibre-native-ffi/bindings/go@mainInstall the C library, then export PKG_CONFIG_PATH
before you build. cgo reads it.
Python
Section titled “Python”Depend on the distribution for your backend and resolve it from the snapshot index. The wheels contain the native library.
[project]dependencies = ["maplibre-native-ffi-vulkan"]
[[tool.uv.index]]name = "maplibre-snapshots"url = "https://maplibre.github.io/maplibre-native-ffi/simple/"explicit = true
[tool.uv.sources]maplibre-native-ffi-vulkan = { index = "maplibre-snapshots" }This index configuration uses uv. The explicit index limits snapshot resolution to this package; all other dependencies continue to resolve from PyPI.
Take one distribution:
maplibre-native-ffi-openglmaplibre-native-ffi-metalmaplibre-native-ffi-vulkan
Depend on the maplibre-native-ffi crate from Git and enable one backend
feature. The build script downloads the matching native artifact.
[dependencies]maplibre-native-ffi = { git = "https://github.com/maplibre/maplibre-native-ffi", features = ["vulkan"] }Enable one backend feature: opengl, metal, vulkan, or webgpu.
Set MAPLIBRE_NATIVE_C_INSTALL_DIR to an install prefix to use your own build
instead.
The package manifest at the repository root defines the Swift package.
.package(url: "https://github.com/maplibre/maplibre-native-ffi", branch: "main")Depend on the MaplibreNativeFFI product. SwiftPM takes the package identity
from the repository name rather than from the manifest, so name it as
maplibre-native-ffi.
.product(name: "MaplibreNativeFFI", package: "maplibre-native-ffi")Install the C library, then export PKG_CONFIG_PATH
before you build.
zig fetch --save git+https://github.com/maplibre/maplibre-native-ffiInstall the C library, then pass
-Dnative-install-dir=<prefix> when you build.
Platforms
Section titled “Platforms”Linux runs the Vulkan and OpenGL backends, with EGL as the OpenGL context provider.
macOS runs the Metal, Vulkan, and OpenGL backends, with EGL as the OpenGL context provider. Apple provides neither Vulkan nor EGL, so a host that chooses one of those backends loads MoltenVK or ANGLE itself.
Windows
Section titled “Windows”Windows runs the Vulkan and OpenGL backends, with WGL as the OpenGL context provider.
Android
Section titled “Android”Android runs the Vulkan and OpenGL backends, with EGL as the OpenGL context provider.
An Android app using Kotlin/JVM depends on a Kotlin runtime AAR. The AAR carries the native library for every ABI and the platform TLS component that Android HTTPS requests require.
implementation("org.maplibre.nativeffi:maplibre-native-ffi-runtime-vulkan:0.202608.0")A Kotlin/Native target gets the native library from its runtime KLIB. Add the matching runtime AAR directly to the module that packages the APK or AAB so that the app also carries the TLS component. Exclude the AAR’s shared library because the Kotlin/Native host library already contains the static runtime.
dependencies { implementation("org.maplibre.nativeffi:maplibre-native-ffi-runtime-vulkan-android:0.202608.0")}
android { packaging { jniLibs.excludes += "**/libmaplibre-native-c.so" }}Initialize the platform once before you create a runtime, passing an
android.content.Context. Every binding exposes this call under its own name.
Android HTTPS requests validate against the app’s trust policy from that point
on. Kotlin/JVM hosts call MaplibreAndroid.initialize(context). Kotlin/Native
hosts create AndroidJniEnvironment and AndroidContextReference values from
host JNI addresses, then pass them to MaplibreAndroid.initialize.
iOS runs the Metal backend, on the device and in the simulator.
OpenHarmony
Section titled “OpenHarmony”OpenHarmony runs the Vulkan and OpenGL backends, with EGL as the OpenGL context provider.
Emscripten runs the WebGPU and OpenGL backends, with WebGL as the OpenGL context provider.