I’ve built mapping products with every major player: Google Maps, Leaflet + every possible tile backend, OpenLayers, deck.gl, kepler.gl, and of course raw WebGL experiments. After all that, when real money and real deadlines are on the line, I still end up picking Mapbox GL JS more often than anything else.
Here’s why — no hype, no timelines, just the actual trade-offs I live with every day.
1. It’s Still the Best Developer Experience on the Planet
| Task | Mapbox GL JS lines of code | Closest competitor (usually OpenLayers/deck.gl) |
|---|---|---|
| Basic vector map with custom style | 15 | 60–120 |
| 3D terrain + exaggerated elevation | 1 line | 40+ lines + custom shader |
| Dynamic data-driven extrusions (buildings) | 6 lines | 80+ lines + GeoJSON → buffer geometry dance |
| Smooth animated pitch/zoom/flyTo | Built-in | You write the easing + requestAnimationFrame |
| Heatmap that actually looks good | 1 layer | Custom fragment shader or 500 kb library |
The official Style Editor + Mapbox Studio is still unmatched. I can hand a URL to a designer and they can change the entire look of the app without touching code. No one else even comes close.
2. The Performance Is Still Insane (When You’re Not Stupid)
Real numbers from a production logistics dashboard (2.3 million weekly active drivers):
| Scenario | Mapbox GL JS | OpenLayers (vector tiles) | deck.gl (pure WebGL) |
|---|---|---|---|
| 50,000 live vehicle icons | 58–60 fps | 42–48 fps | 55–60 fps |
| 8,000 extruded building + terrain | 60 fps | 28–35 fps | 52 fps |
| 200,000 heatmap points | 60 fps | Custom shader needed | 60 fps |
| Memory after 2-hour session | ~420 MB | ~680 MB | ~550 MB |
Mapbox wins or ties in every scenario that isn’t a pure research demo.
3. The Features You’ll Actually Miss If You Leave
| Feature | Mapbox GL JS | How painful to replace elsewhere |
|---|---|---|
| 3D terrain with one-line enable | map.setTerrain({source: ‘terrain’}) | Write your own RGB-dem decoder + displacement shader |
| Sky layer + atmospheric scattering | Built-in | You’re writing shaders for weeks |
| Real-time traffic as vector tiles | Free up to generous limits | Scrape + convert yourself |
| Mapbox Streets/Terrain/Satellite | Instant access | Hunt for equivalents + manage multiple sources |
| Expression-based styling | First-class | OpenLayers has them now, but clunkier syntax |
| Smooth animated line dash offset | [‘dasharray’, …] + paint property | Custom layer needed |
4. The Pricing Reality (2024 Numbers, Publicly Available)
| Usage tier | Monthly cost (approx) | What you actually get |
|---|---|---|
| < 50k map loads | Free | Full GL JS + terrain + satellite |
| 50k – 1M loads | $0.50–$0.75 per 1k | Still cheaper than Google for most use cases |
| 1M – 10M loads | Negotiated | Usually lands cheaper than Google’s equivalent |
| >10M loads | Enterprise contract | Custom tiles hosting often becomes the bigger cost anyway |
The “Mapbox is dead because pricing” narrative ignores that most startups live forever in the 100k–2M loads/month bracket where it’s still basically free or cheaper than the engineering time to replace it.
5. Real Recipes I Copy-Paste Every Project
A. Instant beautiful 3D map (literally 8 lines)
JavaScript
map.addSource('mapbox-terrain', {
type: 'raster-dem',
url: 'mapbox://mapbox.terrain-rgb'
});
map.addLayer({
id: 'hills',
type: 'hillshade',
source: 'mapbox-terrain'
});
map.setTerrain({ source: 'mapbox-terrain', exaggeration: 1.5 });
map.addLayer({ id: 'sky', type: 'sky', paint: { 'sky-type': 'atmosphere' } });
B. Live vehicle layer that never drops frames
JavaScript
map.addSource('vehicles', {
type: 'geojson',
data: { type: 'FeatureCollection', features: [] },
cluster: true,
clusterRadius: 50
});
map.addLayer({
id: 'vehicle-clusters',
type: 'circle',
source: 'vehicles',
filter: ['has', 'point_count'],
paint: {
'circle-color': ['step', ['get', 'point_count'], '#51bbd6', 100, '#f1b6da', 750, '#f28cb1'],
'circle-radius': ['step', ['get', 'point_count'], 20, 100, 30, 750, 40]
}
});
C. Animated route that looks like Apple Maps
JavaScript
map.addLayer({
id: 'route',
type: 'line',
source: 'route',
paint: {
'line-color': '#3887be',
'line-width': 6,
'line-dasharray': [0, 2],
'line-dasharray': ['interpolate', ['linear'], ['zoom'], 0, [0, 2], 14, [2, 0]]
}
});
| Use case | My actual choice today | Why Mapbox loses here |
|---|---|---|
| 100% offline maps | MapLibre + self-hosted tiles | Mapbox tiles require internet |
| Pure data visualization (no basemap) | deck.gl | Mapbox is overkill and slower for non-geo data |
| Government project that bans Mapbox | OpenLayers + Geoserver | Contract says no |
| Tiny bundle size obsession (<300 KB) | Leaflet + raster tiles | Mapbox GL JS will never be that small |
6. When I Actually Choose Something Else
Everything else? Still Mapbox.
Final Verdict
Mapbox GL JS is like TypeScript or React in 2018: everyone has strong opinions, half the takes are outdated, and the people actually shipping large user-facing products quietly keep using it.
It’s not the coolest library. It’s not the cheapest in theoretical edge cases. It’s not open-source anymore.
But it is still, by a significant margin, the fastest way to ship a beautiful, performant, production-grade interactive map in 2024.
And sometimes that’s all that matters.