Repository navigation
Description
Mapbox Version
11.23.1
React Native Version
0.85.3
Platform
Android
@rnmapbox/maps version
10.3.2
Standalone component to reproduce
import Mapbox, { Camera, CircleLayer, MapView, MarkerView, ShapeSource } from "@rnmapbox/maps"
import React from "react"
import { StyleSheet, Text, View } from "react-native"
// Set your own public Mapbox access token (never commit a real one).
Mapbox.setAccessToken(process.env.EXPO_PUBLIC_MAPBOX_ACCESS_TOKEN ?? "REPLACE_WITH_YOUR_OWN_MAPBOX_ACCESS_TOKEN")
// Paris, arbitrary — any two nearby points work.
const CENTER = [2.3522, 48.8566]
const POIS = [
{ id: "a", coordinate: [2.3522, 48.8566], label: "120 m" },
{ id: "b", coordinate: [2.3572, 48.8596], label: "340 m" },
]
// Plain dot on a ShapeSource/CircleLayer — a native GL layer, no image asset,
// no RN bridge per-frame, so it never drifts: this is the reference.
const DOT_RADIUS = 18
const dotShape = {
type: "FeatureCollection",
features: POIS.map((poi) => ({
type: "Feature",
id: poi.id,
geometry: { type: "Point", coordinates: poi.coordinate },
properties: {},
})),
}
const dotLayerStyle = {
circleRadius: DOT_RADIUS,
circleColor: "#2a9d8f",
circleStrokeWidth: 2,
circleStrokeColor: "white",
}
// Same pattern as a typical distance-label marker: a MarkerView pinned at the
// same coordinate as the dot, offset above it. This is a real RN view
// re-projected by rnmapbox every frame — this is the one that drifts on
// Android pan/zoom while the CircleLayer dot above stays glued to its
// coordinate.
const LABEL_GAP = 10
export default function App() {
return (
<View style={styles.container}>
<MapView style={styles.map} styleURL={Mapbox.StyleURL.Street}>
<Camera zoomLevel={13} centerCoordinate={CENTER} />
<ShapeSource id="dots-shape-source" shape={dotShape}>
<CircleLayer id="dots-circle-layer" style={dotLayerStyle} />
</ShapeSource>
{/* Drag the map on Android: the label drifts away from its dot. */}
{POIS.map((poi) => (
<MarkerView
key={poi.id}
coordinate={poi.coordinate}
anchor={{ x: 0.5, y: 1 }}
pointerEvents="none"
>
<View style={styles.labelOffset} pointerEvents="none">
<View style={styles.labelBadge}>
<Text style={styles.labelText}>{poi.label}</Text>
</View>
</View>
</MarkerView>
))}
</MapView>
</View>
)
}
const styles = StyleSheet.create({
container: { flex: 1 },
map: { flex: 1 },
// anchor {x:0.5, y:1} pins the label's bottom-center to the coordinate, then
// this pushes it straight up, clear of the dot's radius + a gap.
labelOffset: { transform: [{ translateY: -(DOT_RADIUS + LABEL_GAP) }] },
labelBadge: {
backgroundColor: "#ffb703",
borderColor: "black",
borderWidth: 1,
borderRadius: 8,
paddingHorizontal: 6,
paddingVertical: 2,
},
labelText: { fontSize: 12, fontWeight: "700", color: "black" },
})Observed behavior and steps to reproduce
Marker is drifting compare to symbol layer even with only 2 markers and a really simple app when user pan/zoom on the map
- Add the App.js in your react native/expo project
- Pan the map
Expected behavior
MarkerView shouldn't be drifting
Notes / preliminary analysis
Happens since May 24, @rnmapbox/maps 10.2.10 → 10.3.1.
What changed: not RN/Expo (those bumped in separate commits, 0.79→0.85 across 7af7239be/348d82d74/9e32a2097). The rnmapbox bump itself is what did it — 10.3.0 hard-forces native Mapbox v10 → v11 (gradle: "❌ ERROR: Mapbox v10 is no longer supported as of @rnmapbox/maps 10.3.0"). Mapbox v10 (what you ran on RN 0.79) didn't have the MarkerView drift; v11 does.
I know in this small example I can use symbolLayer for all the elements, but in my app I need to use animations (zoomIn/zoom out, transform,...) and not just static images so I need to use MarkerView
Activity
mfazekas commentedon Oct 13, 2026
Thanks for the clear reproducer! We reproduced it on current main and looked into where the lag comes from.
MarkerViewon Android is positioned by Mapbox's ownViewAnnotationManager, and it already uses the synchronized update mode by default. A plain native Android view added directly as a Mapbox view annotation (no React Native involved) trails the map by the same amount asMarkerView, so this is a limitation of view annotations in the Mapbox Android SDK rather than something in our wrapper. The map is drawn on its own surface and composited separately from the normal view hierarchy, so during a pan the view can end up a frame behind. Mapbox describes the same limitation in mapbox/mapbox-maps-android#1609.The likely reason you first noticed it after upgrading: in 10.3.0 (#4166) the Android
surfaceViewdefault becametruefor everyone.Options:
SymbolLayer(withImages); layers are drawn as part of the map, so they never drift.<MapView surfaceView={false}>(TextureView). In our measurements the marker then no longer trails the map, but it leads it by a similar amount, and TextureView has some performance cost.MarkerViewwhere you need animated or interactive content, and accept the small lag while the map moves.Since there's nothing we can fix on our side, I'm closing this as an upstream limitation. Feel free to reopen if you find a case where
MarkerViewlags more than a plain Mapbox view annotation.