NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
Last release 6 days ago
15 Sep 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
6 years old
188 releases · first in 2020
One column per quarter.
Fix white artifacts when using non-zero elevation (#6032) (by @NathanMOlson)
GeoJSONSource when rapidly updating data (#6163) (by @andrewda)Map.setTransformRequest parameter type to include null (#6179) (by @madoci)_rotatePitchHandler in the navigation_control.ts file (#6207) (by @daandewaard)Fix use of textureSize call in color relief shader (#5980) (by @mwilsnd)
textureSize call in color relief shader (#5980) (by @mwilsnd)locationOccludedOpacity no longer applicable (#6088) (by @jammie1903)Add setGlobalStateProperty() and getGlobalState() to the map public API (#5613) (by @zbigniewmatysek-tomtom)
setGlobalStateProperty() and getGlobalState() to the map public API (#5613) (by @zbigniewmatysek-tomtom)color-relief layer type to render hypsometric tint from terrain-RGB tiles. (#5742) (by @NathanMOlson)queryRenderedFeatures bounding box crossing antimeridian in globe view. (#5856) (by @msbarry)refreshTiles() for vector tiles (#5875) (by @NathanMOlson)clusterMaxZoom (warning is shown) (#5929) + clarify API docs (by @igalgh)switch statement in hillshade shader (#5972) (by @mwilsnd)Add additional hillshade methods (#5768) (by @NathanMOlson)
refreshTiles() to the map public API (#5806) (by @NathanMOlson)trackUserLocation is off (#5824) (by @tsegarra)Add tile LOD control to the public API (#5719) (by @NathanMOlson)
Only add aria-label on the Marker's element if it does not already has one (#5298) (by @liorchamla)
aria-label on the Marker's element if it does not already has one (#5298) (by @liorchamla)glPixelStore is now properly cleaned after texture updates to avoid glTexSubImage2D calls made on the same gl context acting differently at random (#5730) (by @kubapelc)Added getBounds to GeoJSON source to allow getting the boundaries of the data in it (#5575) (by @HarelM)
getBounds to GeoJSON source to allow getting the boundaries of the data in it (#5575) (by @HarelM)Allow opacity to be set when location becomes invisible in the globe projection. (#5532) (by @geekdenz)
GeoJSONFeature type to library export as it is exposed by querySourceFeatures (#5567) (by @HarelM)Avoid setting marker opacity twice. (#5441) (by @erasta)
Add support for vertical-align in format expression (specification)(#5043). (by @stanislawpuda-tomtom)
vertical-align in format expression (specification)(#5043). (by @stanislawpuda-tomtom)⚠️ Revert changes made in geometry-type (#5331). This change was causing issues in a large number of styles and thus reverted. (by @HarelM)
geometry-type (#5331). This change was causing issues in a large number of styles and thus reverted. (by @HarelM)~~⚠️ Changed geometry-type to identify "Multi-" features (#4877). Use $type which has no "Multi-" support or use in expression to get the previous beh
geometry-type to identify "Multi-" features (#4877). Use $type which has no "Multi-" support or use in expression to get the previous behavior.StyleLayer's queryIntersectsFeature method parameters were moved to QueryIntersectsFeatureParams. (#5276) Wrap the method parameters with {} to solve this (by @HarelM)antialias, preserveDrawingBuffer and failIfMajorPerformanceCaveat must now be defined inside the canvasContextAttributes object on MapOptions. (by @ibesora)on method to return a Subscription to allow for easy unsubscribe (#5080). map.on('x').on('y') => map.on('x'); map.on('y');. (by @HarelM)contextType inside canvasContextAttributes to choose which WebGL version to use (by @ibesora)Event class (#5016) (by @zdila)coveringTiles (tile culling) function for globe (#4937) (by @kubapelc)AJAXError to expose HTTP request details to the "error" event (#4822) (by @jonathanlurie)queryRenderedFeatures by using JavaScript Sets to assess layer membership internally (#4777) (by @tomhicks)error handler (#4613) (by @ibesora)geometry-type filter expression results (#5132) (by @HarelM)GeoJSONSource.setClusterOptions() (#5055) (by @ciscorn)always (#4802) (by @kubapelc)Add support for projection type expression as part of a refactoring of the transform and projection classes (#5139) (by @HarelM)
antialias, preserveDrawingBuffer and failIfMajorPerformanceCaveat must now be defined inside the canvasContextAttributes object on MapOptions. (by @ibesora)Fix smooth mouse wheel zooming (#5154) (by @Al-4SW)
geometry-type filter expression results (#5132) (by @HarelM)⚠️ Change the return type of on method to return a Subscription to allow for easy unsubscribe (#5080) (by @HarelM)
⚠️ Change drag rotate behavior to be around the center of the screen (#5074) (by @HarelM)
Event class (#5016) (by @zdila)GeoJSONSource.setClusterOptions() (#5055) (by @ciscorn)When clustering circles and the promoteId is set to some parameter, the promoted ID is used on non-clustered features and the cluster_id is used on cl
coveringTiles (tile culling) function for globe (#4937) (by @kubapelc)normalizeSpriteURL, sprite URLs must be absolute (#4962)Catches network fetching errors such as CORS, DNS or malformed URL as actual AJAXError to expose HTTP request details to the "error" event (#4822) (by
AJAXError to expose HTTP request details to the "error" event (#4822) (by @jonathanlurie)⚠️ Changed geometry-type to identify "Multi-" features (#4877) (by @HarelM)
geometry-type to identify "Multi-" features (#4877) (by @HarelM)Add support for camera roll angle (#4717) (by @NathanMOlson)
Improve performance of queryRenderedFeatures by using JavaScript Sets to assess layer membership internally (#4777) (by @tomhicks)
queryRenderedFeatures by using JavaScript Sets to assess layer membership internally (#4777) (by @tomhicks)Support globe mode (#3963) (by @HarelM)
Fix circle won't render on mesa 24.1 with AMD GPU (#4062) (by @cutephoton)
Support multiple layers in map.on, map.once and map.off methods (#4570) (by @pstaszek)
map.on, map.once and map.off methods (#4570) (by @pstaszek)maxzoom is less than or equal to clusterMaxZoom since in this case you may see unexpected results. (#4604) (by @andrewharvey)addSource and getSource (#4616) (by @HarelM)fitBounds and cameraForBounds would not display across the 180th meridian (antimeridian) (#4620) (by @YoelRidgway)lngRange. This caused a bug where using transformCameraUpdate caused the maxBounds to stop working just for east/west bounds. (#4625) (by @tomhicks)Prefer local glyph rendering for all CJKV characters, not just those in the CJK Unified Ideographs, Hiragana, Katakana, and Hangul Syllables blocks. (
getStyle() to return a clone so the object cannot be internally changed (#4488) (by @gavinr-maps)undefined (#4587)) (by @HarelM)Emit events when the cooperative gestures option has prevented a gesture. (#4470) (by @tomhicks)
Allow trackpad pinch gestures to break through the cooperativeGestures setting, bringing it in line with other embedded map behaviours, such as Google
cooperativeGestures setting, bringing it in line with other embedded map behaviours, such as Google Maps and Mapbox. (#4465) (by @tomhicks)moveend (#4458) (by @JeroendeJong)style.loadURL abort error being logged when removing style (#4425) (by @madoci)Add sky implementation according to spec (#3645) (by @prozessor13)
Fix terrain listener memory leak when adding and removing Marker (#4284) (by @rczobor)
Update deprecated -ms-high-contrast vendor prefix to (forced-colors: active) and (prefers-color-scheme: light) as appropriate (#4250) (by @stacy-renda…
GeolocateControl to allow a more granular interaction (#3847) (by @MeysamRT76)MapOptions.style optional to be consistent with Map.setStyle(null) (#4151) (by @vicb)aria-label configurable for Map, Marker and Popup (#4147) (by @thom4parisot)<canvas> is focusable only when interactive (#4147) (by @thom4parisot)symbol-placement is line or line-center (#4124) (by @LostDragonist)-ms-high-contrast vendor prefix to (forced-colors: active) and (prefers-color-scheme: light) as appropriate (#4250) (by @stacy-rendall)Fix an issue with moveend zoom being different than the actual current zoom (#4132) (by @HarelM)
Fix drift in zoom that may happen during flyTo and easeTo due to freezeElevation logic. (#3878) (by @olsen232)
Add getData method for GeoJSON Sources to provide the possibility to obtain all the source's features (#4082) (by @smellyshovel)
getData method for GeoJSON Sources to provide the possibility to obtain all the source's features (#4082) (by @smellyshovel)text-translate and icon-translate behaving weirdly and inconsistently with other -translate properties (#3456) (by @kubapelc)showCollisionBoxes) not showing the actual bounding boxes used for collision and click areas. The displayed boxes now match actual collision boxes exactly (#4071) (by @kubapelc)text-translate property for translation instead of the correct icon-translate (#4071) (by @kubapelc)Update Popup's methods addClass and removeClass to return an instance of Popup (#3975) (by @ferdicus)
Popup's methods addClass and removeClass to return an instance of Popup (#3975) (by @ferdicus)distance expression (#4076) (by @HarelM)Added const enum for actor messages to improve readability and maintainability. In tsconfig.json, isolatedModules flag is set to false in favor of gen
isolatedModules flag is set to false in favor of generated JS size. (#3879) (by @zhangyiatmicrosoft)SourceCache that makes unit tests unstable. Eliminate a redundant 'visibility' event fired from Style class. (#3992) (by @zhangyiatmicrosoft)Hide Popup when its parent Marker is behind terrain (#3865) (by @sbachinin)
Improve animation curve when easeTo and flyTo with constraints (#3793) (by @sbachinin)
Add option to position popup at subpixel coordinates to allow for smooth animations (#3710) (by @ericmagnuson)
FullscreenControl when MapLibre is within a ShadowRoot (#3573) (by @dschep)setRTLTextPlugin which can cause 1 or 2 extra frames to render. (#3728) (by @zhangyiatmicrosoft)Fix Style.setState ignoring validate flag (#3709) (by @dsshep)
Style.setState ignoring validate flag (#3709) (by @dsshep)Add setUrl method to RasterTileSource to dynamically update existing TileJSON resource. (#3700) (by @manuelroth)
setUrl method to RasterTileSource to dynamically update existing TileJSON resource. (#3700) (by @manuelroth)⚠️ Remove all global getters and setters from maplibregl, this is to avoid the need to use a global object and allow named exports/imports (#3601). th
⚠️ Remove all global getters and setters from maplibregl, this is to avoid the need to use a global object and allow named exports/imports (#3601). this means the the following methods have changed: (by @HarelM)
maplibregl.version => getVersion()maplibregl.workerCount => getWorkerCount(), setWorkerCount(...)maplibregl.maxParallelImageRequests => getMaxParallelImageRequests(), setMaxParallelImageRequests(...)maplibregl.workerUrl => getWorkerUrl(), setWorkerUrl(...)⚠️ Change attribution to be on by default, change MapOptions.attributionControl to be the type that the control handles, removed MapOptions.customAttribution (#3618). Note: showing the logo of MapLibre is not required for using MapLibre. (by @HarelM)
⚠️ Changed cooperative gesture config and removed the strings from it in favor of the locale variable (#3621) (by @HarelM)
⚠️ Changed the terrain enable disable locale key to match the other keys' styles, updated the typings to allow using locale with more ease (#3621) (by @HarelM)
⚠️ Add the ability to import a script in the worker thread and call addProtocol and removeProtocol there (#3459) - this also changed how addSourceType works since now you'll need to load the script with maplibregl.importScriptInWorkers. (by @HarelM)
⚠️ Changes addProtocol to be promise-based without the usage of callbacks and cancelable (#3433) (by @HarelM)
⚠️ Moved the addSourceType to be a part of the global maplibregl object instead of being per map object (#3420) (by @HarelM)
⚠️ Removed callback usage from map.loadImage in continue to below change (#3422) (by @HarelM)
⚠️ Changed the GeoJSONSource's getClusterExpansionZoom, getClusterChildren, getClusterLeaves methods to return a Promise instead of a callback usage (#3421) (by @HarelM)
⚠️ Changed the setRTLTextPlugin function to return a promise instead of using callback (#3418) this also changed how the RTL plugin code is handled internally by splitting the main thread and worker thread code. (by @HarelM)
⚠️ Remove setCooperativeGestures and getCooperativeGestures functions in favor of cooperativeGestures handler which now has an enabled() or disabled() methods (#3430) (by @HarelM)
⚠️ Changed the underlying worker communication from callbacks to promises. This has a breaking effect on the implementation of custom WorkerSource and how it behaves (#3233) (by @HarelM)
⚠️ Changed the Source interface to return promises instead of callbacks (#3233) (by @HarelM)
⚠️ Changed all the sources to be promises based. (#3233) (by @HarelM)
⚠️ Changed the map.loadImage method to return a Promise instead of a callback usage (#3233) (by @HarelM)
Add "opacity" option and setOpacity method to Marker (#3620) (by @sbachinin)
Created a new example showing how to place a threejs scene as a CustomLayer over maplibre 3d-terrain (#3429) (by @MichaelLangbein)
Changed ImageRequest to be Promise based (#3233) (by @HarelM)
Improved precision and added a subtle fade transition to marker opacity changes (#3431) (by @SnailBones)
Adds support for terrain in setStyle with diff method (#3515, #3463) (by @HarelM)
Upgraded to use Node JS 20 and removed the dependency of gl package from the tests to allow easier development setup. (#3452) (by @HarelM)
Map type in the d.ts file (#3564) (by @HarelM)trackPointer method active (#3434) (by @simondriesen)Actor against XSS attacks in postMessage / onmessage (#3239) (by @HarelM)⚠️ Change attribution to be on by default, change MapOptions.attributionControl to be the type that the control handles, removed MapOptions.customAttr
MapOptions.attributionControl to be the type that the control handles, removed MapOptions.customAttribution (#3618). Note: showing the logo of MapLibre is not required for using MapLibre. (by @HarelM)⚠️ Remove all global getters and setters from maplibregl, this is to avoid the need to use a global object and allow named exports/imports (#3601). Th
maplibregl, this is to avoid the need to use a global object and allow named exports/imports (#3601). This means the the following methods have changed: (by @HarelM)
maplibregl.version => getVersion()maplibregl.workerCount => getWorkerCount(), setWorkerCount(...)maplibregl.maxParallelImageRequests => getMaxParallelImageRequests(), setMaxParallelImageRequests(...)maplibregl.workerUrl => getWorkerUrl(), setWorkerUrl(...)Fix missing export Map type in the d.ts file (#3564) (by @HarelM)
⚠️ Add the ability to import a script in the worker thread and call addProtocol and removeProtocol there (#3459) - this also changed how addSourceType
addProtocol and removeProtocol there (#3459) - this also changed how addSourceType works since now you'll need to load the script with maplibregl.importScriptInWorkers. (by @HarelM)gl package from the tests to allow easier development setup. (#3452) (by @HarelM)setStyle with diff method (#3515, #3463) (by @HarelM)⚠️ Changes addProtocol to be promise-based without the usage of callbacks and cancelable (#3433) (by @HarelM)
addProtocol to be promise-based without the usage of callbacks and cancelable (#3433) (by @HarelM)addSourceType to be a part of the global maplibregl object instead of being per map object (#3420) (by @HarelM)map.loadImage in continue to below change (#3422) (by @HarelM)GeoJSONSource's getClusterExpansionZoom, getClusterChildren, getClusterLeaves methods to return a Promise instead of a callback usage (#3421) (by @HarelM)setRTLTextPlugin function to return a promise instead of using callback (#3418) this also changed how the RTL plugin code is handled internally by splitting the main thread and worker thread code. (by @HarelM)setCooperativeGestures and getCooperativeGestures functions in favor of cooperativeGestures handler which now has an enabled() or disabled() methods (#3430) (by @HarelM)CustomLayer over maplibre 3d-terrain (#3429) (by @MichaelLangbein)trackPointer method active (#3434) (by @simondriesen)Changed ImageRequest to be Promise based (#3233) (by @HarelM)
ImageRequest to be Promise based (#3233) (by @HarelM)WorkerSource and how it behaves (#3233) (by @HarelM)Source interface to return promises instead of callbacks (#3233) (by @HarelM)map.loadImage method to return a Promise instead of a callback usage (#3233) (by @HarelM)Fix mapbox-gl-draw example (#2601, #3394) (by @dBitech)
Fix undefined _onEaseFrame call in Camera._renderFrameCallback() while doing Camera.jumpTo during a Camera.easeTo (#3332) (by @ToHold)
Add getLayersOrder() to Map and Style (#3279) (by @neodescis)
Convert plantuml diagrams to mermaid (#3217) (by @msbarry)
Fix regression introduced in 3.5.0, related to async/await (#3228) (by @birkskyum)
Add setTiles method to RasterTileSource to dynamically update existing tile sources. (#3208) (by @wagewarbler)
Locally rendered glyphs are double resolution (48px), greatly improving sharpness of CJK text. (#2990, #3006) (by @bdon)
Improve error message when a tile can't be loaded (#3130) (by @HarelM)
Copy LICENSE.txt to dist folder so it's included in 3rdpartylicenses.txt by webpack (#3021) (by @miccou)
Map.getLayer() and Style.getLayer() to be StyleLayer | undefined to match the documentation (#2969) (by @RoystonS)Map.addLayer() and Style.addLayer() to allow adding a layer with an embedded source, matching the documentation (#2966) (by @neodescis)Map.setTerrain(options: TerrainSpecification): Map to be Map.setTerrain(options: TerrainSpecification | null): Map per the API spec (#2993) (by @CraigglesO)Map.getTerrain(): TerrainSpecification to be Map.getTerrain(): TerrainSpecification | null for consistency with the setTerrain function (#3020) (by @neodescis)Add support for `text-variable-anchor-offset` symbol style layer property (#2914) (by @drwestco)
text-variable-anchor-offset symbol style layer property (#2914) (by @drwestco)Add cache parameter to `RequestParameters` (#2910) (by @marucjmar)
cache parameter to RequestParameters (#2910) (by @marucjmar)Remove cooperative gesture screen from the accessibility tree since screenreaders cannot interact with the map using gestures (#2857) (by @manuelroth)
cooperated gestures example to the doc.(#2860) (by @visitskyworld)Change all internal exports to named exports(#2711) (by @HarelM)
className option to Marker constructor (#2729) (by @marexandre)Marker constructor parameter (#2756) (by @HarelM)check-for-support example (#2859) (by @visitskyworld)Style.serialize() when the style hasn't loaded yet (#2712) (by @ChrisLoer)checkMaxAngle when a label with length 0 is on the last segment of a line (#2710) (by @ChrisLoer)tap then drag zoom gesture detection to abort when the two taps are far away (#2673) (by @mz8i)Your coding agent can read these notes before it upgrades. Set up the MCP server →