CoursesGIS Basics — A Complete Introduction17.4 MapLibre GL, Mapbox, and Modern Mapping APIs
Module 17: Web GIS & APIs

17.4 MapLibre GL, Mapbox, and Modern Mapping APIs

Build modern interactive web maps with vector tiles and GPU rendering.

Lesson 85 of 100·18 min read

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:

Shell
npm install maplibre-gl

Minimum setup

JavaScript
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:

JSON
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:

JavaScript
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:

JavaScript
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

JavaScript
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

  • Clusteringcluster: true on the GeoJSON source, renders aggregated circles.
  • Heatmaps — dedicated heatmap layer type.
  • 3D buildingsfill-extrusion with per-feature height.
  • Terrainterrain-rgb source + 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.

JavaScript
1import { MapboxLayer } from '@deck.gl/mapbox';
2import { HexagonLayer } from '@deck.gl/aggregation-layers';

Turf.js

Client-side GIS operations:

JavaScript
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.