From mapbox
Guides migration from MapLibre GL JS to Mapbox GL JS, covering shared API, token setup, style config, and Mapbox support/ecosystem benefits.
npx claudepluginhub mapbox/mapbox-agent-skills --plugin mapboxThis skill uses the workspace's default tool permissions.
Expert guidance for migrating from MapLibre GL JS to Mapbox GL JS. Covers the shared history, API compatibility, migration steps, and the advantages of Mapbox's platform.
Guides migration from Google Maps Platform to Mapbox GL JS with API equivalents, pattern translations, initialization examples, and philosophy differences.
Automates Mapbox operations via Composio toolkit and Rube MCP. Discovers tools dynamically with RUBE_SEARCH_TOOLS, manages connections, and executes schema-compliant workflows.
Share bugs, ideas, or general feedback.
Expert guidance for migrating from MapLibre GL JS to Mapbox GL JS. Covers the shared history, API compatibility, migration steps, and the advantages of Mapbox's platform.
MapLibre GL JS is an open-source fork of Mapbox GL JS v1.13.0, created in December 2020 when Mapbox changed their license starting with v2.0.
Timeline:
Key Insight: The APIs are ~95% identical because MapLibre started as a Mapbox fork. Most code works in both with minimal changes, making migration straightforward.
Compelling reasons to choose Mapbox GL JS:
Mapbox offers a generous free tier: 50,000 map loads/month, making it suitable for many applications without cost.
| Aspect | Mapbox GL JS | MapLibre GL JS |
|---|---|---|
| License | Proprietary (v2+) | BSD 3-Clause (Open Source) |
| Support | Official commercial support | Community support |
| Tiles | Premium Mapbox vector tiles | OSM or custom tile sources |
| Satellite | High-quality global imagery | Requires custom source |
| Token | Required (access token) | Optional (depends on tile source) |
| APIs | Full Mapbox ecosystem | Requires third-party services |
| Studio | Full integration | No native integration |
| 3D Terrain | Built-in with premium data | Available (requires data source) |
| Globe View | v2.9+ | v3.0+ |
| API Compatibility | ~95% compatible with MapLibre | ~95% compatible with Mapbox |
| Bundle Size | ~500KB | ~450KB |
| Setup Complexity | Easy (just add token) | Requires tile source setup |
pk. for public tokens)# Remove MapLibre
npm uninstall maplibre-gl
# Install Mapbox
npm install mapbox-gl
// Before (MapLibre)
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
// After (Mapbox)
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
Or with CDN:
<!-- Before (MapLibre) -->
<script src="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.css" rel="stylesheet" />
<!-- After (Mapbox) -->
<script src="https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css" rel="stylesheet" />
// Add this before map initialization
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
Token best practices:
process.env.VITE_MAPBOX_TOKEN or process.env.NEXT_PUBLIC_MAPBOX_TOKENpk.*) for client-side code.env and .gitignore)See mapbox-token-security skill for comprehensive token security guidance.
// Before (MapLibre)
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json', // or your custom style
center: [-122.4194, 37.7749],
zoom: 12
});
// After (Mapbox)
mapboxgl.accessToken = 'pk.your_mapbox_access_token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/standard', // Mapbox style
center: [-122.4194, 37.7749],
zoom: 12
});
Mapbox provides professionally designed, maintained styles:
// Mapbox built-in styles
style: 'mapbox://styles/mapbox/standard'; // Mapbox Standard (default)
style: 'mapbox://styles/mapbox/standard-satellite'; // Mapbox Standard Satellite
style: 'mapbox://styles/mapbox/streets-v12'; // Streets v12
style: 'mapbox://styles/mapbox/satellite-v9'; // Satellite imagery
style: 'mapbox://styles/mapbox/satellite-streets-v12'; // Hybrid
style: 'mapbox://styles/mapbox/outdoors-v12'; // Outdoor/recreation
style: 'mapbox://styles/mapbox/light-v11'; // Light theme
style: 'mapbox://styles/mapbox/dark-v11'; // Dark theme
style: 'mapbox://styles/mapbox/navigation-day-v1'; // Navigation (day)
style: 'mapbox://styles/mapbox/navigation-night-v1'; // Navigation (night)
Custom styles: You can also create and use custom styles from Mapbox Studio:
style: 'mapbox://styles/your-username/your-style-id';
Replace all maplibregl references with mapboxgl:
// Markers
const marker = new mapboxgl.Marker() // was: maplibregl.Marker()
.setLngLat([-122.4194, 37.7749])
.setPopup(new mapboxgl.Popup().setText('San Francisco'))
.addTo(map);
// Controls
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.addControl(new mapboxgl.GeolocateControl());
map.addControl(new mapboxgl.FullscreenControl());
map.addControl(new mapboxgl.ScaleControl());
Some MapLibre plugins should be replaced with Mapbox versions:
| MapLibre Plugin | Mapbox Alternative |
|---|---|
@maplibre/maplibre-gl-geocoder | @mapbox/mapbox-gl-geocoder |
@maplibre/maplibre-gl-draw | @mapbox/mapbox-gl-draw |
maplibre-gl-compare | mapbox-gl-compare |
Example:
// Before (MapLibre)
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
// After (Mapbox)
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
map.addControl(
new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl
})
);
All your map code, events, layers, and sources work identically:
// This code works EXACTLY THE SAME in both libraries
map.on('load', () => {
map.addSource('points', {
type: 'geojson',
data: geojsonData
});
map.addLayer({
id: 'points-layer',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 8,
'circle-color': '#ff0000'
}
});
});
// Events work identically
map.on('click', 'points-layer', (e) => {
console.log(e.features[0].properties);
});
// All map methods work the same
map.setCenter([lng, lat]);
map.setZoom(12);
map.fitBounds(bounds);
map.flyTo({ center: [lng, lat], zoom: 14 });
Must change:
maplibre-gl -> mapbox-gl)mapboxgl.accessToken configurationmapbox:// styles)Stays exactly the same:
setCenter, setZoom, fitBounds, flyTo, etc.)map.on('click'), map.on('load'), etc.)Problem:
// Error: "A valid Mapbox access token is required to use Mapbox GL"
const map = new mapboxgl.Map({...});
Solution:
// Set token BEFORE creating map
mapboxgl.accessToken = 'pk.your_token';
const map = new mapboxgl.Map({...});
Problem:
// Token hardcoded in source
mapboxgl.accessToken = 'pk.eyJ1Ijoi...';
Solution:
// Use environment variables
mapboxgl.accessToken = process.env.VITE_MAPBOX_TOKEN;
// Add to .env file (not committed to git)
VITE_MAPBOX_TOKEN=pk.your_token
// Add .env to .gitignore
echo ".env" >> .gitignore
Problem:
// MapLibre-style URL won't work optimally
style: 'https://demotiles.maplibre.org/style.json';
Solution:
// Use Mapbox style URL for better performance and features
style: 'mapbox://styles/mapbox/streets-v12';
Problem:
// MapLibre plugin won't work
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
Solution:
// Use Mapbox plugin
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
Important: This applies to ALL MapLibre plugins, not just the geocoder. Any
@maplibre/*ormaplibre-gl-*plugin must be replaced with its Mapbox equivalent. Check the Mapbox ecosystem for Mapbox-specific versions of every plugin you use (see Step 8 above for the full mapping table).
Problem:
// Wrong CDN
<script src="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js"></script>
Solution:
// Use Mapbox CDN
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css' rel='stylesheet' />
npm install mapbox-gl (remove maplibre-gl)maplibre-gl -> mapbox-glmaplibre-gl.css -> mapbox-gl.cssmapboxgl.accessToken = 'pk.xxx'.envmapbox://styles/mapbox/streets-v12maplibregl. with mapboxgl.| What | MapLibre | Mapbox |
|---|---|---|
| Package | maplibre-gl | mapbox-gl |
| Import | import maplibregl from 'maplibre-gl' | import mapboxgl from 'mapbox-gl' |
| Token | Optional (depends on tiles) | Required: mapboxgl.accessToken = 'pk.xxx' |
| Style | Custom URL or OSM tiles | mapbox://styles/mapbox/streets-v12 |
| License | BSD (Open Source) | Proprietary (v2+) |
| Support | Community | Official commercial support |
| Tiles | Requires tile source | Premium Mapbox tiles included |
| APIs | Third-party | Full Mapbox API ecosystem |
| API | ~95% compatible | ~95% compatible |
Bottom line: Migration is easy because APIs are nearly identical. Main changes are packaging, token setup, and style URLs. The result is access to Mapbox's premium tiles, ecosystem, and support.
Related skills:
Mapbox GL JS:
Migration Support:
For detailed information on specific topics, load these reference files:
references/api-compatibility.md -- Full list of 100% compatible APIs + side-by-side migration examplereferences/exclusive-features.md -- Mapbox-exclusive features (APIs, Studio, Advanced) + React/Vue framework examplesreferences/why-mapbox.md -- Why Choose Mapbox (Production, Dev Teams, Business) + Performance Comparison