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.
Show the sky in globe view, fading out with altitude instead of with the globe to mercator transition ( #8464 ) (by @birkskyum )
Marker is behind terrain with a CPU ray walk over the DEM instead of a depth-buffer readback, removing a GPU stall per marker while a map with terrain moves (#8387) (by @johncarmack1984)setStyle calling Map.setTerrain with the wrong this, which made a terrain change in a style diff throw (#8451) (by @HarelM)Stop the scale control forcing a synchronous layout and rewriting its DOM on every frame of a pan or zoom ( #8403 ) (by @cherenkov )
symbol-placement: line features that share a label, which took time quadratic in the number of features that chain together (#8436) (by @cherenkov)fill-extrusion-rounded-corner-distance rounding distance to tile units once per tile instead of once per feature (#8435) (by @cherenkov)fill-extrusion-vertical-gradient disappearing over 3D terrain, where the gradient was computed from the extrusion's height above sea level instead of its own height (#8410) (by @ArcSolver)idle even when nothing could animate and restarted transitions that were still running (#8376) (by @cherenkov)fill-extrusion-rounded-corner-distance rounding every feature twice, which over-rounded the corners and inflated the vertex count (#8429) (by @cherenkov)Map#project returning an incorrect on-screen point for a location behind the camera. It now returns a point outside the viewport, on the side through which the location left the screen, so DOM markers and popups are moved off-screen as expected. (#8292) (by @schickm)…loading a right-to-left text plugin, which deprecates setRTLTextPlugin and getRTLTextPluginStatus ( #8343 ) (by @HarelM )
setRTLTextPlugin and getRTLTextPluginStatus (#8343) (by @HarelM)OffscreenCanvas where available, removing a main-thread stall of tens of milliseconds on GPU-accelerated browsers when a sprite loads (#8339) (by @cherenkov)setStyle() throwing while terrain is still loading because an intermediate render tried to compile a terrain shader before the replacement style initialized its projection (#6824) (by @miakh)updateData property removals throwing after geometry-only updates or retaining previously updated values (#8372) (by @jokrasno)undefined as not given in jumpTo, easeTo and flyTo; they were coerced to NaN (#8373) (by @vlumi)Not implemented. error that broke panning and zooming when the projection was changed while the camera was moving, on maps with terrain enabled or a transformCameraUpdate callback (#8351) (by @lazerg)400x300 fallback size when the container is shown before the resize observer's first notification is delivered (#8277) (by @spliffone)MercatorTransform throwing when it is resized to a zero width, and skip the matrix calculation of every projection while the transform has a zero width or height (#8374) (by @avosa)idle from firing for the transition duration after the map was otherwise done, and could ease the sky and the light on a different curve from the layers (#8348) (by @cherenkov)Add map.getStyleUrl() , which returns the URL the style was loaded from, or null when the style was given as an object ( #7109 ) (by @bradymadden97 an
map.getStyleUrl(), which returns the URL the style was loaded from, or null when the style was given as an object (#7109) (by @bradymadden97 and @giswqs)Intl.Segmenter instances used for text shaping on first use instead of at import, shaving several milliseconds off loading MapLibre on the main thread (#8337) (by @cherenkov)Marker pin once and clone it per marker, so creating many default markers takes roughly half the constructor time (#8340) (by @cherenkov)fill-color as the foreground color (#7747) (by @bradymadden97 and @deniial00)maxCanvasSize, which previously lowered the rendered resolution silently (#8200) (by @str0kes)dem dimension mismatch error, and empty raster tiles render as transparent (#1551) (by @clement-igonet)before layer in map.moveLayer before reordering, so passing the id of a layer that does not exist leaves the layer order untouched instead of dropping the moved layer out of it (#8301) (by @lazerg)getCameraAltitude() returning NaN under globe and vertical-perspective, which disabled marker terrain occlusion and the camera terrain check; the altitude now follows the sphere (#6584) (by @bigmistqke and @patte)setTiles producing stale tile URLs when loadTile runs in the same frame (#8323) (by @johncarmack1984 and @nostrorom)symbol-height-offset stays visible until it is behind the planet (#8316) (by @clement-igonet)Support the style specification's font-faces property, with map.setFontFaces and map.getFontFaces and improve complex script languages such as Devanag
font-faces property, with map.setFontFaces and map.getFontFaces and improve complex script languages such as Devanagari, Khmer, Burmese and Hebrew (#8237) (by @HarelM)font-faces (#8237) (by @HarelM)GPUInitializationError from the Map constructor when the WebGL2 context cannot be created, instead of firing an error event no listener can catch and returning a partially constructed map (#8066) (by @johncarmack1984)url. The source starts empty and makes no network request; call updateImage({image}) or updateImage({url}) later to show an image (#8167) (by @mondsichtung)Style#triggerSymbolPlacement, which re-places symbols when something the map cannot see for itself has moved them (#8208) (by @lucaswoj){validate: false} skip the style snapshot the style setters only build as error context, so adding layers one at a time no longer serializes the whole style on every call (#8259) (by @lazerg)project() and queryTerrainElevation disagreeing with the rendered terrain surface when the elevation lookup sampled a different DEM zoom than the drawn mesh (#8212) (by @johncarmack1984)Add support for symbol-height-offset and symbol-height-anchor layout properties, which raise icons and text above the map. symbol-height-anchor select
symbol-height-offset and symbol-height-anchor layout properties, which raise icons and text above the map. symbol-height-anchor selects whether the offset is measured from the terrain surface (ground, the default) or from the zero elevation datum (absolute) (#7827) (by @HarelM)text-size/icon-size (#8175) (by @mondsichtung)center, zoom, bearing, pitch and roll being ignored when the map was created with a minZoom or minPitch option, since applying those limits marked the transform as modified (#5932)color-relief DEM texture once per tile instead of on every frame (#8209)Add experimental ImageSource.setWarp and ImageSource.getWarp , choosing between a auto , perspective and a flat warp of the image ( #8172 ) (by @Harel
ImageSource.setWarp and ImageSource.getWarp, choosing between a auto, perspective and a flat warp of the image (#8172) (by @HarelM)Fix DOM.sanitize leaving dangerous attributes behind when multiple consecutive attributes are present. Iterating the live NamedNodeMap from elem.attri
DOM.sanitize leaving dangerous attributes behind when multiple consecutive attributes are present. Iterating the live NamedNodeMap from elem.attributes while calling removeAttribute skipped the attribute directly after a removed one, so a second dangerous attribute (for example an ontoggle on a <details open> element) could survive sanitisation and later execute (#8189) (by @0xKirisame)CustomRenderMethodInput.defaultProjectionData.projectionTransition, which was hardcoded to 1 for the whole globe/mercator transition, so a custom layer jumped straight to the fully bent globe while every other layer eased (#8169) (by @mondsichtung)Avoid a per-query Array.sort() in cross-tile symbol matching ( TileLayerIndex.findMatches ), claiming the lowest-index unclaimed candidate in a single
Array.sort() in cross-tile symbol matching (TileLayerIndex.findMatches), claiming the lowest-index unclaimed candidate in a single pass instead; reduces main-thread symbol-placement cost on dense/coincident symbol layers (#7797) (by @pholmstr)texelFetch for exact DEM and color-relief elevation stop lookups instead of normalized texture coordinate arithmetic (#7640) (by @johncarmack1984)gfx.color_management.mode = 1 in Firefox) (#8125) (by @tnikkel)transformRequest, so ImageSource.updateImage no longer loses the image it was just handed and an aborted tile is no longer fetched (#8071) (by @mondsichtung)fill-extrusion-rounded-corner-distance producing spikes: corner arcs now land on the integer tile grid, and corners created by tile clipping are left sharp (#8153) (by @HarelM)Make fired/listened map events typed. This means that map.on("something", ...) (and once , listens ) will now give you an typescript error and better
map.on("something", ...) (and once, listens) will now give you an typescript error and better autocomplete. If you relied on firing/listening custom events via the map, this still works via the escape hatches map.fire("something" as any) -> map.on("something" as any, ...) (#8072) (by @CommanderStorm)StyleImageInterface give a {renderWithWebGL} callback as its data, an escape hatch for plugin developers and advanced users that renders a style image on the GPU instead of moving its pixels through the CPU. Nothing new is possible that pixels could not already express, but an image that changes often, such as an animated icon, gets more performant (#7954) (by @lucaswoj)ImageSource, VideoSource and CanvasSource leaking a GPU texture on every image update and on removal, and a resized texture losing its wrap and filter settings (#8094) (by @mondsichtung)map.queryRenderedFeatures() sometimes causing "Out of bounds" error due to race condition while loading tile data (#8064) (by @smvjohansenbouvet)Add the fill-extrusion-rounded-corner-distance layout property, which replaces each fill-extrusion corner with an arc spanning the given distance (in
fill-extrusion-rounded-corner-distance layout property, which replaces each fill-extrusion corner with an arc spanning the given distance (in meters) along the adjacent edges. The distance is clamped to 20% of each adjacent edge's length so that short edges don't collapse, and near-straight corners (turns below 5°) are left untouched. Defaults to 0, which keeps corners sharp (#7934) (by @CommanderStorm)Add support for updating an ImageSource with an already-decoded image (HTMLImageElement, HTMLCanvasElement, ImageBitmap or ImageData) directly via Ima
ImageSource with an already-decoded image (HTMLImageElement, HTMLCanvasElement, ImageBitmap or ImageData) directly via ImageSource.updateImage({image}), skipping the network request (#7944) (by @mondsichtung)GeoJSONSource.getClusterOptions to get a source's current cluster options (cluster, clusterMaxZoom, clusterRadius) (#7948) (by @lazerg)global-state expressions in sky.*, light.* and projection.type properties (#7966, #7967, #7968) (by @CommanderStorm)MapOptions.rotateSpeed and MapOptions.pitchSpeed, the degrees the bearing/pitch change per pixel dragged (#7949) (by @clement-igonet)role=img for non-interactive default markers and role=button when they become interactive (#7790) (by @cat0825)RasterTileSource.setTiles/setUrl is called while the source contains errored tiles (#7911) (by @lazerg)exp + rational arithmetic instead of atan/sin/cos), avoiding float32 cancellation and imprecise hardware transcendentals near the equator; the runtime GPU atan-error measurement/correction this superseded has also been removed (#7419) (by @clement-igonet)RasterTileSource.loadTile and ImageSource.load where a tile/image aborted during an awaited transformRequest passed an undefined AbortController into the image request queue, crashing it with TypeError: Cannot read properties of undefined (reading 'signal') (#8004) (by @jan-grzybek)setTerrain not destroying the previously active terrain when switching to a new configuration, which leaked its GPU resources and left the old source still configured as a terrain source (#7990) (by @lazerg)…justified the added complexity. To ease this breaking change, we have also refactored how we handle the case that no webgl is avaliable (e.g. due to b…
The following incorporates all the pre-releases for version 6 changes. Check-out our migration guide from v5 to v6 for more information.
maplibre-gl.mjs). The UMD bundles (maplibre-gl.js, maplibre-gl-csp.js) are no longer published. The CSP-specific bundle is also dropped: the ESM build loads its worker as a real URL, so worker-src blob: is no longer required. Consumers using <script src=".../maplibre-gl.js"> must switch to <script type="module">, and consumers using import maplibregl from 'maplibre-gl' must switch to import * as maplibregl from 'maplibre-gl' or named imports. See the docs ESM section or our migration guide for migration steps. (#6254) (by @birkskyum)styleimagemissing is now a notify-only event instead of the previous callback that allowed to provide an image. This aligns the event with standard event semantics (notify, not resolve). Use Map.setMissingStyleImageResolver to on-demand supply images instead via an function that can now also be async. (#7892) (by @birkskyum)Map now composes a Camera instead of extending it (Map extends Evented directly and forwards the camera API). The internal map.transform was removed — use map's public API instead or open a PR if you need something that's not exposed. Removed the internal transform.getMatrixForModel helper (#7800) (by @HarelM)Maps' BoxZoom handler from MapLibreZoomEvent to MapBoxZoomEvent, added the rollstart/roll/rollend and style.load (as MapStyleLoadEvent) events to MapEventType, and added event classes and type-map for Marker, Popup, GeolocateControl and FullscreenControl. Removed MapDataEvent: the data/dataloading/dataabort events are now MapSourceDataEvent | MapStyleDataEvent, so source data events carry the full source info (sourceId, tile, sourceDataType, …). Added MapMovementEvent as the type for all camera-transition events (move/zoom/rotate/pitch/roll/drag and their start/end variants). Evented is now generic over an event-type map (Evented<EventType>) and is abstract, so subclasses get strongly-typed on/once/off automatically without re-declaring overloads — this also types the events on Camera/Style (via MapEventType) and on the sources (via the new SourceEventType) (#7789) (by @HarelM)#pragma mapbox to #pragma maplibre in case you have shader code that relied on it. (#7761) (by @HarelM)zoomLevelsToOverscale default value was changed to 4 to support better handling of high level zoom with dense labels. This might have a side effect of changing a bit the results of queryRenderedFeatures and some rendering of polygon center label. To revert this change, set the value to undefined (#7537) (by @HarelM)GeoJSONSource.setData (waitForCompletion) and remove the return value of this to allow future changes to the API (#7538) (by @HarelM).on("error").
See caniuse.com/webgl2 for ecosystem support and our RFC for details. (#7453) (by @CommanderStorm)__$json__ before properties that used to be an object. It also parses them back, but this is still a breaking change if you assumed this bug existed. (#6992) (by HarelM){get,set}LayoutProperty, {get,set}PaintProperty to be the actual type instead of string/any (#7481) (by @CommanderStorm)Hash-based location control (the option that syncs map state to the URL like #map=5/1/2) to use URLSearchParams internally. This improves extensibility for custom use cases, but may break existing code that relies on the previous implementation. It also changes how certain edge cases are parsed—for example, strings like #10%2F3.00%2F-1.00 are now accepted, and hashes like #foo are normalized to #foo=. (#7073) (by @CommanderStorm)map.setTerrain, which was previously applied unchecked (#7941) (by @HarelM)layers[3].paint.line-color, layers[3].filter) instead of just logging the bare error message (#7869) (by @CommanderStorm)Map.setMissingStyleImageResolver for resolving missing style images with sync or async callbacks (#7850) (by @birkskyum)RasterTileSource#setPremultiplyAlpha(false) to preserve raw RGBA tile values when alpha is used for data instead of opacity (#7235) (by @plantain).@mapbox/whoots-js dependency by inlining its single getTileBBox helper (#7838) (by @qorexdevs)setImages broadcast to once per animation frame, fixing O(n²) serialization overhead when adding many images (#7614) (by @bradymadden97)fill-layer-opacity and line-layer-opacity paint properties, which apply opacity to the entire layer output uniformly (#7570) (by @CommanderStorm)line-opacity-driven offscreen rendering introduced in #7490 (#7764) (by @CommanderStorm). The overlap-artefact fix is now driven by line-layer-opacity instead.ProjectionData matrix backing types for renderer and custom layer projection matrices (#6316) (by @cat0825)flat to opt out of interpolation for constant shader varyings (#7661) (by @birkskyum)bindAttribLocation calls (#7644) (by @birkskyum)terrainSkirtLength, which allows the removal of visually unappealing vertical artifacts when using a terrain along with a transparent background (#7523) (by @safwat-halaby)getProjectionData function in custom layer args objects (#7471) (by @kubapelc)sideEffects as CSS-only in package metadata, which may improve tree-shaking and reduce bundle size in some bundlers (#7258) (by @CommanderStorm)line-opacity, but purposefully not for transparent line-color properties, thus still allowing transparent colors to stack their effect. (#7490) (by @CommanderStorm)raster-dem sources passed to map.addSource, which were previously skipped. Stop a source type the style spec has no schema for, such as one registered with addSourceType, from failing the whole style. Previously only canvas was let through (#7941) (by @HarelM)line-layer-opacity/fill-layer-opacity clipping away a subsequent layer that shares the same source (#7867) (by @CommanderStorm)Actor.sendAsync now rejects with an AbortError on abort (#7826) (by @kamil-sienkiewicz-asi)undefined properties during worker serialization (#7801) (by @xavierjs)queryRenderedFeatures (#7765) (by @ckolin)Framebuffer is not complete error on transient GPU resource loss (e.g. when a tab wakes from sleep); incomplete framebuffers now self-heal on the next frame instead (#7303) (by @johanrd)line-dasharray step transition lags one zoom level when the step's branches are data-driven (#7705) (by @lucaswoj)Validate the terrain passed to map.setTerrain, which was previously applied unchecked (#7941) (by @HarelM)
map.setTerrain, which was previously applied unchecked (#7941) (by @HarelM)layers[3].paint.line-color, layers[3].filter) instead of just logging the bare error message (#7869) (by @CommanderStorm)raster-dem sources passed to map.addSource, which were previously skipped. Stop a source type the style spec has no schema for, such as one registered with addSourceType, from failing the whole style. Previously only canvas was let through (#7941) (by @HarelM)Improve terrain render-to-texture preparation performance by skipping sources that are not rendered to terrain textures (#7863) (by @DoFabien)
Map.setMissingStyleImageResolver for resolving missing style images with sync or async callbacks (#7850) (by @birkskyum)styleimagemissing listeners to resolve the current image request; use Map.setMissingStyleImageResolver instead (#7892) (by @birkskyum)RasterTileSource#setPremultiplyAlpha(false) to preserve raw RGBA tile values when alpha is used for data instead of opacity (#7235) (by @plantain).⚠️ Map now composes a Camera instead of extending it (Map extends Evented directly and forwards the camera API). The internal map.transform was remove
Map now composes a Camera instead of extending it (Map extends Evented directly and forwards the camera API). The internal map.transform was removed — use map's public API instead or open a PR if you need something that's not exposed. Removed the internal transform.getMatrixForModel helper (#7800) (by @HarelM)line-layer-opacity/fill-layer-opacity clipping away a subsequent layer that shares the same source (#7867) (by @CommanderStorm)Drop the archived @mapbox/whoots-js dependency by inlining its single getTileBBox helper (#7838) (by @qorexdevs)
@mapbox/whoots-js dependency by inlining its single getTileBBox helper (#7838) (by @qorexdevs)setImages broadcast to once per animation frame, fixing O(n²) serialization overhead when adding many images (#7614) (by @bradymadden97)Improve terrain rendering performance by avoiding unnecessary terrain data lookups during Mercator render-to-texture passes (#7833) (by @DoFabien)
Actor.sendAsync now rejects with an AbortError on abort (#7826) (by @kamil-sienkiewicz-asi)⚠️ All map events are now real classes that are instantiated when they are fired. Renamed MapLibreZoomEvent to MapBoxZoomEvent, added the rollstart/ro
MapLibreZoomEvent to MapBoxZoomEvent, added the rollstart/roll/rollend and style.load (as MapStyleLoadEvent) events to MapEventType, and added event classes and type-map for Marker, Popup, GeolocateControl and FullscreenControl. Removed MapDataEvent: the data/dataloading/dataabort events are now MapSourceDataEvent | MapStyleDataEvent, so source data events carry the full source info (sourceId, tile, sourceDataType, …). Added MapMovementEvent as the type for all camera-transition events (move/zoom/rotate/pitch/roll/drag and their start/end variants). Evented is now generic over an event-type map (Evented<EventType>) and is abstract, so subclasses get strongly-typed on/once/off automatically without re-declaring overloads — this also types the events on Camera/Style (via MapEventType) and on the sources (via the new SourceEventType) (#7789) (by @HarelM)⚠️ Update maplibre-gl-style-spec to version 25, which has a breaking change in legacy expression validation (#7792) (by @HarelM)
Add fill-layer-opacity and line-layer-opacity paint properties, which apply opacity to the entire layer output uniformly (#7570) (by @CommanderStorm)
fill-layer-opacity and line-layer-opacity paint properties, which apply opacity to the entire layer output uniformly (#7570) (by @CommanderStorm)Revert the line-opacity-driven offscreen rendering introduced in #7490 (#7764) (by @CommanderStorm). The overlap-artefact fix is now driven by line-la
line-opacity-driven offscreen rendering introduced in #7490 (#7764) (by @CommanderStorm). The overlap-artefact fix is now driven by line-layer-opacity instead.#pragma mapbox to #pragma maplibre in case you have shader code that relied on it. (#7761) (by @HarelM)⚠️ Disable icon scaling with offset, this is a render breaking change which we have decided to incorporate in both maplibre-gl-js and maplibre-native…
ProjectionData matrix backing types for renderer and custom layer projection matrices (#6316) (by @cat0825)Framebuffer is not complete error on transient GPU resource loss (e.g. when a tab wakes from sleep); incomplete framebuffers now self-heal on the next frame instead (#7303) (by @johanrd)Optimization: vertex shader opacity culling for lines and fills #7711 (by @xavierjs)
line-dasharray step transition lags one zoom level when the step's branches are data-driven (#7705) (by @lucaswoj)Use a shared FBO for the terrain cache render to texture #7637 (by @xavierjs)
flat to opt out of interpolation for constant shader varyings (#7661) (by @birkskyum)Replace texImage2D with texStorage2D for immutable textures (#7643) (by @birkskyum)
bindAttribLocation calls (#7644) (by @birkskyum)Adopt isolatedDeclarations and switch dts emitter from tsgo to oxc (#7566) (by @birkskyum)
Improve 3D terrain performance (#7549) (by @lucaswoj)
Replace dts-bundle-generator with rolldown-plugin-dts for 78.2x faster .d.ts generation. (#7564) (by @birkskyum)
line-opacity, but purposefully not for transparent line-color properties, thus still allowing transparent colors to stack their effect. (#7490) (by @CommanderStorm)Add a new map creation option, terrainSkirtLength, which allows the removal of visually unappealing vertical artifacts when using a terrain along with
terrainSkirtLength, which allows the removal of visually unappealing vertical artifacts when using a terrain along with a transparent background (#7523) (by @safwat-halaby)⚠️ Switch to an ESM-only distribution (maplibre-gl.mjs). The UMD bundles (maplibre-gl.js, maplibre-gl-csp.js) are no longer published. The CSP-specifi
maplibre-gl.mjs). The UMD bundles (maplibre-gl.js, maplibre-gl-csp.js) are no longer published. The CSP-specific bundle is also dropped: the ESM build loads its worker as a real URL, so worker-src blob: is no longer required. Consumers using <script src=".../maplibre-gl.js"> must switch to <script type="module">, and consumers using import maplibregl from 'maplibre-gl' must switch to import * as maplibregl from 'maplibre-gl' or named imports. See the docs ESM section for migration steps. (#6254) (by @birkskyum)⚠️ zoomLevelsToOverscale default value was changed to 4 to support better handling of high level zoom with dense labels. This might have a side effect
zoomLevelsToOverscale default value was changed to 4 to support better handling of high level zoom with dense labels. This might have a side effect of changing a bit the results of queryRenderedFeatures and some rendering of polygon center label. To revert this change, set the value to undefined (#7537) (by @HarelM)⚠️ Remove the second parameter from GeoJSONSource.setData (waitForCompletion) and remove the return value of this to allow future changes to the API (
GeoJSONSource.setData (waitForCompletion) and remove the return value of this to allow future changes to the API (#7538) (by @HarelM)…justified the added complexity. To ease this breaking change, we have also refactored how we handle the case that no webgl is avaliable (e.g. due to b…
.on("error").
See caniuse.com/webgl2 for ecosystem support and our RFC for details. (#7453) (by @CommanderStorm)⚠️ Support geojson nested objects, this is a breaking change as it encodes __$json__ before properties that used to be an object. It also parses them…
__$json__ before properties that used to be an object. It also parses them back, but this is still a breaking change if you assumed this bug existed. (#6992) (by HarelM){get,set}LayoutProperty, {get,set}PaintProperty to be the actual type instead of string/any (#7481) (by @CommanderStorm)⚠️ Refactored the Hash-based location control (the option that syncs map state to the URL like #map=5/1/2) to use URLSearchParams internally. This imp
Hash-based location control (the option that syncs map state to the URL like #map=5/1/2) to use URLSearchParams internally. This improves extensibility for custom use cases, but may break existing code that relies on the previous implementation. It also changes how certain edge cases are parsed—for example, strings like #10%2F3.00%2F-1.00 are now accepted, and hashes like #foo are normalized to #foo=. (#7073) (by @CommanderStorm)getProjectionData function in custom layer args objects (#7471) (by @kubapelc)sideEffects as CSS-only in package metadata, which may improve tree-shaking and reduce bundle size in some bundlers (#7258) (by @CommanderStorm)GPU performance optimization: Render halo and glyph in a single pass (-40% Time Reduction) (#7436) (by @xavierjs)
load, idle, render) (#7077) (by @CommanderStorm)Popup not updating its position when switching between terrain/globe projections (#7468) (by @CommanderStorm)Add touchZoomRotate.setZoomRate() and touchZoomRotate.setZoomThreshold() to customize touch zoom speed and pinch sensitivity (#7271) (by @itisyb)
touchZoomRotate.setZoomRate() and touchZoomRotate.setZoomThreshold() to customize touch zoom speed and pinch sensitivity (#7271) (by @itisyb)makeRequest in workres as well (#7451) (by @HarelM)opacity and opacityWhenCovered in Marker and MarkerOptions to accept number in addition to string, and add maplibregl-marker-covered CSS class to Marker element when covered by 3D terrain or a globe (#7433) (by @YuChunTsao)_demMatrixCache lookup being wasted cycles by actually using the cache (#7400) (by @CommanderStorm)_contextRestored when map was initialized without a style (#7432) (by @mvanhorn)Make line-cap, line-miter-limit, and line-round-limit data-driven properties, allowing per-feature values (#7351) (by @CommanderStorm)
line-cap, line-miter-limit, and line-round-limit data-driven properties, allowing per-feature values (#7351) (by @CommanderStorm)load, idle, render) (#7077) (by @CommanderStorm)setPaintProperty or setLayoutProperty (#6954) (by @Willjfield and @CommanderStorm)fitBounds and fitScreenCoordinates respect the zoomSnap map option by snapping the zoom level down to keep bounds fully visible (#7332 (by @CommanderStorm)jumpTo, easeTo, and flyTo respect the zoomSnap map option by snapping the zoom level to the nearest valid increment (#7333 (by @CommanderStorm)setState crash when switching styles while globe projection is active (#7314) (by @ashwinuae)map.remove() immediately after creation by canceling in-flight style URL loads (#7368) (by @CommanderStorm)fitBounds ignoring maxZoom option in vertical-perspective projection (#7372) (by @CommanderStorm)fill-pattern (#7326) (by @k-yle)Add missing promoteId parameter to geojson worker and refactor communication object (#7320) (by @HarelM)
Add compatibility for ES2020 (#7283) (by @claudiobgit)
referrerPolicy option to RequestParameters to allow controlling the referrer policy for tile requests (#7278) (by @Bingtagui404)Accept: image/webp header for image requests (#7293) (by @johanrd)DOM.remove() and DOM.mouseButton() wrappers; use native APIs directly (baseline 2015) (#7295) (by @johanrd)setTransformRequest accept an async function in addition to a sync function. (#7184) (by @kikuomax)jumpTo (#7267) (by @HarelM)playing event listener and pause video on source removal (#7279) (by @johanrd)"reloading" state (#7284) (by @katemihalikova)GeolocateControl leaking a movestart listener on the map after removal, which could also crash if the control was in active tracking state when removed (#7286) (by @johanrd)click listener not removed on remove(), leaking the handler added in #7028 (#7287) (by @johanrd)setTerrain(null) (#7288) (by @johanrd)PauseablePlacement (#7079) (by @garethbowker)Fix update GeoJSON when using diff update by updating geojson-vt package (#7257) (by @HarelM)
Fix cannot read properties of undefined (reading 'range') by updating geojson-vt package (#7245) (by @HarelM)
Add Etag unmodified support to optimize vector tile reloading (#7074) (by @rivkamatan)
boxZoom.boxZoomEnd option to customize the action after Shift-drag box selection (#6397) (by @itisyb)resampling paint property for raster, hillshade, and color-relief layers (#7074) (by @larsmaxfield)Fix Firefox "Alpha-premult deprecated for non-DOM uploads" warning (#7128) (by @birkskyum)
LngLatBounds.toArray() to use a more precise type (#7156) (by @n4n5)anisotropicFilterPitch map option to set the pitch above which the anisotropic filter is applied to all raster layers, the default of which is 20° (#7134) (by @larsmaxfield)icon-text-fit rendering by correctly unpacking packed shader values in symbol_sdf.vertex.glsl, with render-test coverage (#7141, fixes #6953) (by @pcardinal)Add support for click events on Marker (#7028) (by @ganesh8068)
pseudo option to FullscreenControl to force CSS-based fullscreen mode instead of native fullscreen API. Users might want this because this is faster on some devices (#7076) (by @CommanderStorm)GlobeControl not updating when Map.setProjection() is called programmatically (#7005, #7075) (by @CommanderStorm)map.getProjection() returning undefined after calling map.setProjection() with the default "mercator" projection (#7072) (by @CommanderStorm)prefers-reduced-motion media query is active, we now no longer display the pulsing GeoLocation animation (#7066) (by @CommanderStorm)Refactor _updateWorkerData (#6983) (by @wayofthefuture)
_updateWorkerData (#6983) (by @wayofthefuture)zoomSnap option to Map to allow snapping zoom levels to a grid when zooming in and out; aligns the behavior across all UI patterns (keyboard, scroll wheel, on-screen zoom buttons, double-click, double-tap). Previously, pressing +/- on the keyboard zoomed to rounded whole integers, more or less than 1 zoom level when starting from a fractional zoom. Now any number can be specified for zoomSnap; a value of 1.0 produces the rounded whole integer behavior across all UI patterns. (#6941) (by @mizmay)Add padding option to Popup class to prevent popups from being positioned too close to map container edges (#5978) (by @yuiseki and @lucaswoj)
padding option to Popup class to prevent popups from being positioned too close to map container edges (#5978) (by @yuiseki and @lucaswoj)style.load event on style diff (#6880) (by @lesbaa)format expressions (#6907) (by @1ec5)setStyle emit a style.load event. (#2587, #4757) (by @lesbaa)Support global state expression for layer visibility (#6659) (by @melitele)
LngLatBounds#intersects returning false for bounds spanning 360° or more (#6863) (by @lucaswoj)minZoom or maxZoom due to old copies from transformCameraUpdate taking precedence. transformCameraUpdate is now called from setMinZoom and setMaxZoom to allow user to control subsequent changes to zoom (#6766) (by @Auspicus)Prevent redundant DEM border backfilling by tracking state, moved tile manager logic to helper files (#6756) (by @HarelM)
updateData, setData, and overzoomed tiles (#6738, #6772) (by @lucaswoj)queryTerrainElevation to use higher zoom level tiles when possible (#6791) (by @HarelM)static modifier as part of mlt package (#6796) (by @HarelM)LngLatBounds#intersects now returns true when bounds touch along an edge or at a corner (#6802) (by @lucaswoj)Text labels can now include relatively uncommon Chinese, Japanese, Korean, and Vietnamese characters, as well as characters from historical writing sy
GeoJSONSource#updateData (#6668) (by @lucaswoj)Add support for MapLibre Tiles (MLT) by using encoding: 'mlt' in vector source definition (#6570) (by @Salkin975 and @HarelM)
encoding: 'mlt' in vector source definition (#6570) (by @Salkin975 and @HarelM)experimentalZoomLevelsToOverscale flag to MapOptions to allow controlling how many zoom levels to slice and how many to scale. It seems to have better performance at high zoom levels. It can prevent Safari crashes in some scenarios by setting it to 4 or less. (by @HarelM)constrainOverride setter in TransformHelper.apply (#6642) (by @larsmaxfield)⚠️ Refactor SourceCache to TileManager (#6635) - this is not a breaking change since SourceCache is not part of the public API, but if you have a plug…
GeoJSONSource#updateData when called on small diffs (#6562) (by @lucaswoj)glyphs property at the root level, interpret the text-font property as a cascading fallback list of font names and render all text using local or system fonts. (#4564) (by @1ec5)text-field, try to render it locally instead of crashing. (#4564) (by @1ec5)now() function in timeControl API to complete the API and enable external code to read controlled time (#6644) (by @bjperson)white-space: nowrap to prevent wrapping (#6647) (by @stroebjo)Add time control API (setNow, restoreNow, isTimeFrozen) for deterministic rendering, enabling frame-by-frame video export and deterministic testing (#
setNow, restoreNow, isTimeFrozen) for deterministic rendering, enabling frame-by-frame video export and deterministic testing (#6544) (by @bjperson)isHidden logic in the worker by adding a new optional roundMinZoom parameter (#6547) (by @HarelM)transformConstrain callback to the Map options to override the transform's constrain with new type TransformConstrainFunction; refactor transform constructor options to a TransformOptions object (#6484) (by @larsmaxfield)Improve fading - dynamic bi-directional raster cross-fading and self fading (#6469) (by @wayofthefuture)
Enable documentation admonitions in Material for MkDocs. (#6455) (by @morehawes)
line-dasharray (#5812) (by @lucaswoj)Fix case where retain loaded children does not retain uppermost loaded children (#6399) (by @wayofthefuture)
Fix _updateRetainedTiles checking for children when children length is 1 overscaled tile "child" (#6388) (by @NathanMOlson)
_updateRetainedTiles checking for children when children length is 1 overscaled tile "child" (#6388) (by @NathanMOlson)global-state for layers added after loading style (#6361) (by @melitele)global-state object from Style to expression to fix a hack that was introduced in previous versions (#6366) (by @melitele)load and idle events when source TileJSON fails to load (#5430) (by @melitele)Fix accuracy circle on locate user control (#5432) (by @geekdenz)
global-state in paint ...-pattern properties (#6301) (by @melitele)text-color when using format within step (#5833) (by @sim51)mergeSourceDiffs: handle add/remove/removeAll (#6342) (by @lhapaipai)global-state in layout properties icon-size and text-size (#6308) (by @melitele)Pass document's lang to Tiny-SDF to render Simplified and Traditional Chinese characters (#6223) (by @mapmeld)
lang to Tiny-SDF to render Simplified and Traditional Chinese characters (#6223) (by @mapmeld)global-state expressions in layout properties (#6209) (by @melitele)coveringTiles method to the public API of the map object (#6292) (by @HarelM)Your coding agent can read these notes before it upgrades. Set up the MCP server →