Roadmap¶
MapLibre Compose is still primarily developed by one person in his spare time. Therefore, there are no target dates for the completion of projects listed on this page.
We'd love for the community to help move the project forward. Community contributions don't just take the form of code changes in pull requests; a number of the projects below require an interested party to do research, investigation, or experiment with some proof of concept.
If you'd like to get involved, please join us in our Slack channel.
On deck¶
These projects are in progress or ready to start writing code. Community contributions are highly welcome.
Desktop Parity¶
Status: Nearly done 🏁
The goal is to support Compose Desktop platforms (macOS, Windows, and Linux) on par with our current level of support for Android and iOS.
Desktop is now built on the published
maplibre-native-ffi Kotlin
Multiplatform bindings, rather than JNI bindings and a vendored MapLibre Native
checkout of our own. The camera, gestures, styles, sources, layers, expressions,
images, feature queries, Compose resource loading, and the offline manager all
work. The bridge between MapLibre's renderer and Compose's is a replaceable
integration point rather than something wired into Skiko's internals.
Next steps:
- Add support for platform location services on macOS, Windows, and Linux. This is the last piece. Device heading is not something MapLibre Native provides on desktop, so a desktop map will show position without a compass direction.
Native core integration on Android and iOS¶
Status: Needs Exploration 🔍
The goal is to wrap just the MapLibre Native C++ core on Android, iOS, and
desktop with one common Kotlin JVM+Native wrapper. Desktop consumes
maplibre-native-ffi, but
Android uses MapLibre Native's Java/Kotlin bindings and iOS its Obj-C ones. Each
has a different API, so our multiplatform API tends toward the
lowest-common-denominator of all three.
The desktop work above is the evidence this is worth doing: it is a full map implementation on the FFI, and several capabilities MapLibre Native offers are sitting unused behind it simply because there is no cross-platform API to reach them.
Research Areas:
- Explore using
maplibre-native-ffion Android, with code to integrate with an Android Surface instead of an AWT Canvas. - Explore using its Kotlin/Native targets on iOS, with code to integrate with a Metal layer.
- Explore unifying those platforms behind a single, thin,
expect/actualinterface on top of MapLibre Native.
JS Parity¶
Status: Needs Exploration 🔍
The goal is to support Compose apps in the browser. Which map draws them is no longer settled.
The existing work binds
MapLibre GL JS to Kotlin JS, and a
partial browser implementation is built on it. The alternative is the same
MapLibre Native core the other platforms use.
maplibre-native-ffi has
gained WebGPU and WebGL support on wasm, and its TypeScript bindings — for the
browser, Node, Bun, Deno, and ArkTS — are further along than its Kotlin/Wasm
ones. Wrapping those from Kotlin JS is the same shape of work as wrapping
MapLibre GL JS, which is what makes this a real choice rather than a wish.
Compositing MapLibre Native's output into Compose has been prototyped
successfully, so the browser could be the same platform as everywhere else
rather than a separate one.
It might not work. MapLibre Native was never meant to run in a browser, and finding that out is part of the exploration. Deciding between the two paths comes before deciding what to build next on either.
Next steps if MapLibre GL JS stays:
- Add support for programmatic layer styling (sources, layers, expressions, images, etc).
- Add support for browser location services.
- Update to MapLibre GL JS v5 for 3d globe support.
Documentation¶
Status: Needs Exploration 🔍 but some parts are shovel ready
The goal is to overhaul the documentation to make it easier for newcomers to use the library, and to make LLMs more reliable at writing correct code using MapLibre Compose.
Next steps:
- Improve the demo app, fixing known bugs and adding demos showing the capabilities of MapLibre Compose.
- Add inline examples to the documentation site (requires JS parity above) to go with code snippets.
Investigation needed:
- Explore the Q&A section to understand points of common confusion.
- Build a tutorial-style exploration of the library, covering basic concepts and real-world use cases.
- Explain the style composition and expressions DSL from the Kotlin perspective for an audience who may not be familiar with the MapLibre Style Spec.
- Explore generating a useful
llms.txtfile for the documentation site. - Explore improving the usefulness of context about MapLibre Compose on Context7.
Devex improvements¶
Status: Needs Exploration 🔍 but some parts are shovel ready
The project would benefit from work to improve the experience of developing MapLibre Compose for desktop. The biggest pain points right now are:
- Regressions due to limited automatic tests on all platforms.
- Brittle local development setup.
Next steps:
Investigation needed:
- Explore testing strategies for testing map behavior on all platforms.
- Explore benchmarking strategies for map rendering and other logic on all platforms.
Road to v1.0¶
These projects should be completed before a v1.0 release of MapLibre Compose, but are not currently being worked on. If you're interested and would like to take them on, community contributions are of course still welcome!
WASM Parity¶
Status: Needs Exploration 🔍
The goal is to support Compose apps in the browser using Kotlin WASM. It faces
the same open question as JS parity above — MapLibre GL JS or MapLibre Native —
and maplibre-native-ffi offers a binding on each side of it: TypeScript for
Kotlin JS, Kotlin/Wasm here.
Next steps:
- Decide the path, together with JS parity. Both targets can reach either map, so this is one decision rather than two, unless something found along the way splits them.
- If MapLibre GL JS: explore how much of the Kotlin JS binding can be shared with Kotlin WASM, and build a proof of concept.
- If MapLibre Native: build minimal support on the Kotlin/Wasm bindings — map loading and style switching — and find out what a browser does to a renderer that never expected one.
Improve controls on desktop and web¶
Status: Needs Exploration 🔍
The goal is to build an intuitive experience controlling the map on all platforms. MapLibre Native for iOS and Android already provide a rich set of gestures for those mobile platforms, so the focus here is on desktop and web.
Desktop now has a working set, tuned to match MapLibre GL JS: drag to pan, scroll and double-click to zoom, right-drag or ctrl-drag to rotate and tilt, and keyboard control throughout. Touchscreens on the Desktop FFI host use Android-style pan, pinch, rotate, shove, quick-zoom, and velocity gestures. What is left is covering input devices such as multi-touch trackpads and the accessibility needs the current controls do not yet reach.
Research Areas:
- Explore map controls conventions on desktop and web for zooming, panning, tilting, and rotating using mouse, keyboard, and multi-touch trackpads.
- Explore conventions for maps popular in different regions: Google Maps, Apple Maps, Amap, Baidu Maps, Naver Map, Kakao Maps, Yandex Maps, Mappls, Maps.me
- Explore the available input APIs on macOS, Linux (X11 and Wayland), Windows, and web browsers.
- Design a set of controls that work well on all platforms, considering platform-specific input devices and accessibility features.
Imperative escape hatches¶
Status: Needs Exploration 🔍
Styling is declarative: you compose sources and layers into the map and MapLibre
Compose applies the difference. That works well for content you own and not at
all for content you did not write. Changing the visibility, filter, or zoom
range of a layer that came from the base style is a recurring request, and today
the answers are to replace the layer with Anchor.Replace and reproduce its
properties, or to fetch the style JSON and edit it before handing it to the map.
Both are workarounds for the same missing thing.
Once every platform is on maplibre-native-ffi, the escape hatch may already
exist. Its handles are an imperative map API, so exposing them — opt-in, and
marked as delicate — would let an application blocked on something we have not
wrapped reach past us rather than wait for us, with the same API everywhere.
Doing that today would mean exposing a different one per platform, which is what
makes #538 hard to
answer well.
Fill in the missing map capabilities¶
Status: Blocked 🚧
MapLibre Native can do a number of things MapLibre Compose has no cross-platform
API for, among them feature state, style light, custom geometry sources, the
location indicator layer, alternative projections, style transition options,
HTTP header transforms, supplying missing style images on demand, resource
transforms, merging offline databases, and
static map snapshots —
which maplibre-native-ffi can now produce by reading a rendered map back to
the CPU.
These are deliberately not being built yet. Doing any of them today means
writing the same feature four times — against the Android SDK, the iOS SDK,
maplibre-native-ffi, and MapLibre GL JS — and throwing three of those away
once the native core integration above lands. They become one implementation
each afterwards, which is why that work comes first.
Snapshots carry one extra requirement, since we would like to style them the
same way interactive maps are styled: the style API has to be usable without a
MaplibreMap composable to hang it on.
Long term¶
These projects are unlikely to be worked on until after a v1.0 release of MapLibre Compose. But if you're interested and would like to take them on, community contributions are of course still welcome!
Support secondary platforms (car, watch, tv, etc)¶
Status: Needs Exploration 🔍
The goal is to provide some support for building maps that are used on secondary platforms, such as cars, watches, and TVs. Not all these platforms support Compose UI, so this may involve writing bare KMP wrappers for MapLibre Native on some platforms, or rendering map snapshots, or integrating with some alternative UI toolkits.