17.4 MapLibre GL, Mapbox, and Modern Mapping APIs
Build modern interactive web maps with vector tiles and GPU rendering.
Key takeaways
- MapLibre GL is the leading open-source library for modern vector-tile web maps.
- Style specifications define data sources, layers, and symbology in JSON.
- Client-side analytics (deck.gl, Turf.js) runs alongside map display for rich interactivity.
Introduction
The last decade transformed web mapping. Vector tiles, WebGL rendering, and style specifications now enable web maps that rival desktop GIS in sophistication. This lesson covers how to build them with MapLibre and its ecosystem.
MapLibre GL
An open-source fork of Mapbox GL JS (forked at v1.13, 2020; now independent community). Features:
- GPU-accelerated vector tile rendering.
- 3D terrain, fill-extrusion, pitch / bearing.
- Clustering, heatmaps, symbol placement.
- Event handling (click, hover, etc.).
- Extensible with custom layers, protocols.
Installation:
npm install maplibre-glMinimum setup
1import maplibregl from 'maplibre-gl';
2import 'maplibre-gl/dist/maplibre-gl.css';Styles
A MapLibre style is a JSON document describing:
- sources — where data comes from (vector tiles, GeoJSON URLs, raster tiles, images).
- layers — how to render data (fill, line, symbol, circle, etc.).
- sprite — image atlas for icons.
- glyphs — PBF font files.
Minimal style:
1{
2 "version": 8,
3 "sources": {
4 "osm": {
5 "type": "raster",
6 "tiles": ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
7 "tileSize": 256
8 }
9 },
10 "layers": [
11 { "id": "osm", "type": "raster", "source": "osm" }
12 ]
13}Adding your data
GeoJSON source, rendered with a layer:
1map.on('load', () => {
2 map.addSource('parks', {
3 type: 'geojson',
4 data: 'https://example.com/parks.geojson'
5 });
6 map.addLayer({
7 id: 'parks-fill',
8 type: 'fill',
9 source: 'parks',
10 paint: {
11 'fill-color': '#0f58ff',
12 'fill-opacity': 0.4
13 }
14 });
15});Expressions
Dynamic styling based on attributes:
1'fill-color': [
2 'interpolate', ['linear'], ['get', 'pop_density'],
3 0, '#ffffff',
4 100, '#b5d4ff',
5 500, '#0f58ff'
6]A choropleth with 5 lines of JSON — no server-side styling needed.
Interactivity
1map.on('click', 'parks-fill', (e) => {
2 const f = e.features[0];
3 new maplibregl.Popup()
4 .setLngLat(e.lngLat)
5 .setHTML(`<h3>${f.properties.name}</h3>${f.properties.description}`)
6 .addTo(map);
7});Advanced features
- Clustering —
cluster: trueon the GeoJSON source, renders aggregated circles. - Heatmaps — dedicated
heatmaplayer type. - 3D buildings —
fill-extrusionwith per-feature height. - Terrain —
terrain-rgbsource + map tilt for relief. - Animations — time-based filtering with
setFilter.
deck.gl layers
deck.gl lets you add WebGL-rendered layers (hex bins, arcs, paths, 3D) inside a MapLibre map. For dashboards with large point sets, deck.gl outperforms MapLibre's native layers.
1import { MapboxLayer } from '@deck.gl/mapbox';
2import { HexagonLayer } from '@deck.gl/aggregation-layers';Turf.js
Client-side GIS operations:
import * as turf from '@turf/turf';Turf runs on the client, so users can run spatial analysis without server calls. Slower than PostGIS for large operations but great for UX.
Mapbox-specific features
Mapbox GL JS (v2+) has some features not in MapLibre:
- Mapbox-hosted tiles and styles.
- Commercial support.
- Navigation SDK.
Choose based on licensing and ecosystem needs.
Other modern libraries
- OpenLayers — vector and raster; supports more CRSs than MapLibre.
- CesiumJS — 3D globe.
- Leaflet — classic, raster-first.
- deck.gl — WebGL analytical layers, composable with MapLibre.
- kepler.gl — Uber's data-viz dashboard on top of deck.gl.
Self-check exercises
1. How does MapLibre render vector tiles — client-side or server-side?
Client-side. The server delivers compressed MVT files; the browser's GPU renders them in real time using the style specification. This is why MapLibre can restyle, animate, and interact without server round-trips once tiles are loaded. Rendering is handled by WebGL shaders; the CPU handles only coordination and event handling.
2. Why are style expressions useful?
They let you compute styling dynamically from feature attributes at render time — a choropleth based on a property, icons chosen by type, text labels assembled from multiple fields, colours interpolated by zoom level. All without regenerating tiles or maintaining multiple tile sets. The style JSON becomes a declarative specification of how data should look.
3. Turf.js vs PostGIS — when to use which?
Turf for client-side interactivity on modest-size data (hundreds to thousands of features). Runs in the browser, responds in milliseconds. PostGIS for heavy-duty server-side analysis over millions of features. Often combined: PostGIS pre-processes the data, sends it as GeoJSON to the client, Turf handles live modifications (user buffers, intersects in the UI).
Summary
- MapLibre GL JS is the open-source modern web map library.
- Styles are JSON — sources + layers + expressions.
- deck.gl adds analytical WebGL layers; Turf.js runs GIS in the browser.
- Vector-first, interactive, GPU-accelerated is the new default.
Further reading
- MapLibre documentation and examples gallery.
- Mapbox GL JS documentation (similar API).
- deck.gl documentation.
- Turf.js documentation and sandbox.