English for MapLibre Developers
Vocabulary for developers building interactive maps with MapLibre GL JS — vector tiles, the style spec, layers, sources, and clustering — for teams discussing mapping features in English.
MapLibre GL JS is an open-source library for rendering interactive, vector-tile-based maps in the browser using WebGL, born as a community fork after Mapbox GL JS changed its license. Its vocabulary comes from the broader GIS (geographic information systems) world — tiles, layers, sources — combined with its own declarative style specification. If your team builds mapping features, here’s the English you’ll need for design and performance discussions.
Tiles and Sources
Vector tile — a compact, pre-processed chunk of map data (roads, buildings, boundaries) for a specific geographic area and zoom level, rendered client-side rather than shipped as a pre-rendered image. “We switched from raster tiles to vector tiles — the map now re-styles instantly when we toggle dark mode, instead of needing a whole new set of pre-rendered images.”
Source — the data a map pulls from, whether a vector tile server, a GeoJSON file, or a raster tile endpoint; defined once and referenced by one or more layers. “Don’t duplicate the GeoJSON in two places — register it once as a source, and let both the point layer and the label layer reference that same source.”
Tileset — the full collection of tiles across all zoom levels for a given dataset, typically hosted and served by a tile provider. “The building footprints only render above zoom 14 — that’s just how the tileset was generated, not a bug in our style.”
Style and Layers
Style spec
The style spec is MapLibre’s declarative JSON format describing every visual aspect of a map — which layers exist, their colors, their data sources, and how they respond to zoom.
“The whole visual identity of the map lives in one style JSON file — changing the water color from blue to teal is a one-line edit, not a code change.”
Layer
A layer is a single visual element drawn from a source — a line layer for roads, a fill layer for land use, a symbol layer for labels — stacked in a defined paint order.
“Move the label layer above the fill layers in the stack — right now city names are getting drawn underneath the land-use polygons and disappearing.”
Paint vs. layout properties
MapLibre distinguishes paint properties (color, opacity, width — can change without re-parsing geometry) from layout properties (visibility, text field — affect placement and require more work to update).
“Animating opacity is cheap because it’s a paint property — animating a layout property like text size would force a full re-layout of every label on screen.”
Interaction and Performance
Viewport — the currently visible geographic area and zoom level of the map, which determines which tiles need to be fetched and rendered.
“We’re fetching data for the entire dataset instead of just the current viewport — filtering server-side to the visible bounds would cut the payload dramatically.”
Clustering — grouping nearby points into a single aggregated marker at low zoom levels, expanding into individual points as the user zooms in.
“With 40,000 markers, rendering them all individually froze the map — enabling clustering on the source means only a few dozen cluster circles render at the city-wide zoom level.”
Symbol collision — MapLibre’s automatic handling of overlapping labels/icons, hiding some to avoid visual clutter, based on layout property priority.
“Some store labels aren’t showing at this zoom — that’s symbol collision handling, not a missing-data bug. Increasing their priority in the layout would fix it.”
Common Mistakes
| Mistake | Correction |
|---|---|
| Calling every visual element “a layer” | Sources hold data; layers define how that data is drawn — keep the two separate in discussion. |
| Animating a layout property expecting it to be cheap | Only paint properties are cheap to animate; layout changes trigger heavier recalculation. |
| Loading the full dataset regardless of zoom | Filter or tile the data so only what’s in the current viewport and zoom level is fetched. |
| Assuming missing labels are a data bug | Check symbol collision and layer priority before assuming the underlying data is incomplete. |
Practice Exercise
- Explain, in two sentences, the difference between a source and a layer to someone new to MapLibre.
- Write a short PR description for enabling clustering on a point layer with 40,000+ markers.
- Draft a code review comment explaining why an opacity animation is cheaper than a text-size animation.