This repository is a working reference for using MapLibre Native inside Slint applications.
The important thing here is not packaging polish. The important thing is that the combination actually works today across desktop platforms, with a reusable Slint component surface in src/.
- A reusable Slint component library centered on
src/maplibre.slint - A reusable C++ backend library target (
maplibre-native-slint::mbgl-slint) you can link from your own CMake app - A canonical C++ backend integration that works on Linux, Windows, and macOS
- A practical reference for people who want to build their own Slint + MapLibre app
- A place to validate backend choices such as WebGPU (
wgpu-native) and Metal/OpenGL fallbacks
- Not yet a polished end-user SDK
- Not yet an installable, versioned package (no
find_package/ system install yet) — you consume it viaFetchContent/add_subdirectory, see Use It In Your Own App - Not a "everything is magically wired for you" drop-in — you still write the small
MMapAdapterwiring in your ownmain(seecpp/main.cpp)
Today, the most honest way to describe this repository is:
If you want to build a Slint application that embeds MapLibre, this repository shows a real cross-platform way to do it.
If you want something that works today, use the C++ path as the reference implementation.
- The reusable Slint API lives in
src/ - The authoritative backend wiring lives in
cpp/main.cpp - The demo shell lives in
cpp/map_window.slint
The Rust demo exists to mirror the same Slint component contract, but it depends on maplibre-native-rs and its current 0.8.x API surface. It is still only practical on Linux today. Treat it as an experimental companion, not the primary integration path.
Platform-specific build guides:
- Linux: Ubuntu 24.04 Build Guide
- Windows: Windows 11 Build Guide
- macOS: macOS Apple Silicon Build Guide
Typical Linux build:
git clone https://github.com/maplibre/maplibre-native-slint.git
cd maplibre-native-slint
git submodule update --init --recursive
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/cpp/maplibre-slint-exampleThe default build prefers the WebGPU backend with wgpu-native when available.
For Windows and macOS specifics, use the platform guides above.
The public Slint entrypoint is src/maplibre.slint:
import { MMapView, MMapAdapter } from "@maplibre-native-slint/maplibre.slint";The key exported symbols are:
MMapView: the reusable visual map componentMMapAdapter: the global bridge between the Slint UI and a native backend
Minimal UI usage looks like this:
import { MMapView } from "@maplibre-native-slint/maplibre.slint";
export component App inherits Window {
preferred-width: 800px;
preferred-height: 600px;
map := MMapView {
style-url: "https://demotiles.maplibre.org/style.json";
center-lat: 35.6895;
center-lon: 139.6917;
zoom: 10;
}
}That is the reusable UI layer.
What still needs to be provided by the host application is the native backend wiring for MMapAdapter. The canonical example of that wiring is cpp/main.cpp.
The repository is consumable directly from another CMake project — no system install needed. Fetch it and link the reusable backend target maplibre-native-slint::mbgl-slint, which publicly propagates MapLibre Native, Slint, cpr, the GL/WebGPU libraries, and the backend headers:
include(FetchContent)
FetchContent_Declare(
maplibre-native-slint
GIT_REPOSITORY https://github.com/maplibre/maplibre-native-slint.git
GIT_TAG <pin-a-commit>
)
FetchContent_MakeAvailable(maplibre-native-slint)
add_executable(my-app main.cpp)
# Import the reusable Slint components via the @maplibre-native-slint alias.
slint_target_sources(my-app my.slint
LIBRARY_PATHS maplibre-native-slint=${maplibre-native-slint_SOURCE_DIR}/src)
target_link_libraries(my-app PRIVATE maplibre-native-slint::mbgl-slint)Your main.cpp wires the Slint MMapAdapter callbacks to a SlintMapLibre
instance (from slint_maplibre_headless.hpp, provided by the target). Copy
cpp/main.cpp as the starting point.
The default build uses WebGPU (wgpu-native). To use OpenGL instead, disable
WebGPU and select a backend explicitly — a bare -DMLN_WITH_WEBGPU=OFF
fails fast with a message telling you to pick one:
cmake -B build -DMLN_WITH_WEBGPU=OFF -DMLN_WITH_OPENGL=ONA system-installed Slint is used if found, otherwise Slint is built from source.
A system Slint built against a foreign Qt/ICU can bake its RUNPATH into your
binary and break portability, so force a self-contained build with:
cmake -B build -DMLN_SLINT_USE_SYSTEM=OFFFor a fully self-contained, no-Qt result (kiosk / embedded), combine it with the winit + FemtoVG Slint backend:
cmake -B build \
-DMLN_WITH_WEBGPU=OFF -DMLN_WITH_OPENGL=ON \
-DMLN_SLINT_USE_SYSTEM=OFF \
-DSLINT_FEATURE_BACKEND_QT=OFF \
-DSLINT_FEATURE_BACKEND_WINIT=ON \
-DSLINT_FEATURE_RENDERER_FEMTOVG=ONsrc/m-map-view.slintdefines the reusable map componentsrc/m-map-adapter.slintdefines the backend bridge contractsrc/maplibre.slintis the public entrypoint
cpp/src/slint_maplibre_headless.cppholds the current production-grade backend logic- It is packaged as the
mbgl-slintlibrary target (aliasmaplibre-native-slint::mbgl-slint) so apps and tests link it instead of recompiling the sources cpp/main.cppwiresMMapAdapterto that backendcpp/map_window.slintis a demo shell showing how to use the reusable component
rust/main.slintmirrors the same Slint component contract as the C++ demorust/src/maplibre.rswiresMMapAdaptertomaplibre-native-rs- This path is useful for experimentation on Linux, but it is not the repository's primary story today
| Platform | Status | Notes |
|---|---|---|
| Linux x86_64 | Good | Regularly exercised; best-supported development path |
| Windows x64 | Good | Working desktop path |
| macOS Apple Silicon | Good | Working desktop path |
| Platform | Status | Notes |
|---|---|---|
| Linux x86_64 | Experimental | Tracks maplibre-native-rs 0.8.x; best place to validate the Rust path |
| Windows x64 | Not practical | Blocked by maplibre-native-rs maturity |
| macOS Apple Silicon | Not practical | Blocked by maplibre-native-rs maturity |
This is why the C++ backend remains the canonical reference implementation in this repository.
The current implementation uses a GPU-to-CPU readback pipeline:
- MapLibre Native renders into its headless frontend using the selected backend
- The rendered frame is read back into CPU memory as
mbgl::PremultipliedImage - Pixels are copied into a
slint::SharedPixelBuffer MMapAdapter.frameis updatedMMapViewdisplays that frame and forwards interactions back to the backend
This is not the final ideal architecture, but it is robust and cross-platform enough to serve as a practical reference.
Current desktop backend preferences:
- Linux: WebGPU (
wgpu-native) by default - Windows: WebGPU (
wgpu-native) by default - macOS: WebGPU (
wgpu-native) by default, with Metal still useful as a comparison/fallback path
Examples:
# Default desktop build
cmake -B build -DCMAKE_BUILD_TYPE=Release
# Explicit WebGPU / wgpu-native
cmake -B build -DCMAKE_BUILD_TYPE=Release -DMLN_WITH_WEBGPU=ON -DMLN_WEBGPU_IMPL_WGPU=ON
# macOS Metal fallback / comparison
cmake -B build -DCMAKE_BUILD_TYPE=Release -DMLN_WITH_METAL=ON -DMLN_WITH_OPENGL=OFF -G Xcode
# Explicit OpenGL fallback
cmake -B build -DCMAKE_BUILD_TYPE=Release -DMLN_WITH_WEBGPU=OFF -DMLN_WITH_OPENGL=ONsrc/- reusable Slint component APIcpp/- canonical C++ backend integration and demo apprust/- Linux-oriented experimental Rust backend integrationvendor/- MapLibre Native and other vendored dependenciesdocs/build_guides/- platform-specific build guidesdocs/testing.md- testing instructions
Relevant test/documentation entrypoints:
For the Rust backend specifically:
- use Rust 1.90 or newer (
maplibre-native-rs0.8.x requires it) - on Linux, the default backend is OpenGL and
cargo testbuildsmaplibre-nativefrom source throughmaplibre-native-rs - renderer integration tests are opt-in via
MAPLIBRE_NATIVE_SLINT_RUN_RENDERER_TESTS=1so CI can stay headless by default
For day-to-day validation, the most important checks are:
- the C++ demo builds and launches on Linux, Windows, and macOS
- the reusable Slint contract in
src/stays compatible with both demo shells - the Rust demo remains aligned with the same
MMapView/MMapAdaptercontract on Linux
Near-term goals:
- Keep the reusable Slint API in
src/and thembgl-slinttarget stable enough for direct consumption - Keep the C++ backend as the authoritative cross-platform reference
Longer-term possibilities:
- an installable/exported package (
find_package(maplibre-native-slint)) so downstream apps do not needFetchContent - better packaging so users do not need to think about the C++ toolchain
- a lower-overhead rendering path that avoids GPU-to-CPU readback
These are goals, not promises. The current value of this repository is that it already demonstrates a real working integration.
- Run
git submodule update --init --recursive - Follow the platform-specific build guide for your OS
- On Linux and Windows with WebGPU, make sure LLVM/libclang is available for
bindgen
- Make sure your machine has network access for style and tile loading
- On Linux, ensure a graphical session is available if you are launching the desktop demo directly
- MapLibre Native Slack: #maplibre-native
- OSM US Slack invite: slack.openstreetmap.us
- MapLibre website: maplibre.org
Copyright (c) 2025 MapLibre contributors.
This project is licensed under the BSD 2-Clause License. See LICENSE.
This repository integrates multiple components with their own licenses:
- MapLibre Native: BSD
- Slint: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0