maplibre-mapbox-migration · git:20261105.bac4ee9 · 2026-11-05 · sha256 7985378d96af3144

maplibre-mapbox-migration git:20261105.bac4ee9B

Immutable. This exact content never changes and is served at /api/v1/blob/7985378d96af3144.

---
name: maplibre-mapbox-migration
description: Migrating from Mapbox GL JS to MapLibre GL JS — package and import changes, removing the access token, choosing tile sources, plugin equivalents, and what you gain or give up. Use when moving an existing Mapbox map to MapLibre.
metadata:
  status: provisional
---

# Mapbox to MapLibre Migration

This skill guides you through migrating an application from **Mapbox GL JS** to **MapLibre GL JS**. The two libraries share a common ancestry (MapLibre forked from Mapbox GL JS v1.13 in December 2020), so the API is largely the same. The main changes are: swap the package, replace the namespace, remove the Mapbox access token, and **choose a new tile source** (MapLibre does not use `mapbox://` styles).

**Primary reference:** [MapLibre official Mapbox migration guide](https://maplibre.org/maplibre-gl-js/docs/guides/mapbox-migration-guide/).

## When to Use This Skill

- Migrating an existing Mapbox GL JS app to MapLibre
- Evaluating MapLibre as an open-source alternative to Mapbox
- Understanding API compatibility and what breaks
- Choosing tile sources and services after moving off Mapbox

## Why Migrate to MapLibre?

Common reasons teams switch from Mapbox to MapLibre:

- **Open-source license** — MapLibre is BSD-3-Clause; no vendor lock-in or proprietary terms
- **No access token** — The library does not require a Mapbox token; tile sources may have their own keys or none (e.g. OpenFreeMap)
- **Cost** — Avoid Mapbox map-load and API pricing; use free or fixed-cost tile and geocoding providers
- **Self-hosting** — Use your own tiles (PMTiles, tileserver-gl, Martin) or any third-party source
- **Community** — MapLibre is maintained by the MapLibre organization and community; style spec and APIs evolve in the open
- **Community-supported funding** — MapLibre is funded by donations from many companies and individuals; there is no single commercial backer, so the project stays aligned with the community
- **Open vector tile format (MLT)** — MapLibre offers [MapLibre Tile (MLT)](https://maplibre.org/maplibre-tile-spec/), a modern alternative to Mapbox Vector Tiles (MVT) with better compression and support for 3D coordinates and elevation; supported in GL JS and Native, and can be generated with Planetiler

**What you give up:** Mapbox Studio integration, Mapbox-hosted tiles and styles, Mapbox Search/Directions/Geocoding APIs, official Mapbox support.

## Understanding the Fork

- **Dec 2020:** Mapbox GL JS v2.0 switched to a proprietary license. The community forked v1.13 as **MapLibre GL JS**. [MapLibre organization](https://github.com/maplibre) and [GL JS repo](https://github.com/maplibre/maplibre-gl-js) are the canonical homes.
- **API:** MapLibre GL JS v1.x is largely backward compatible with Mapbox GL JS v1.x. Most map code (methods, events, layers, sources) works with minimal changes.
- **Releases since the fork:** MapLibre has moved ahead with its own version line. v2.2 added 3D terrain and v3 moved to WebGL2; v4 introduced Promises in public APIs (replacing many callbacks); v5 added the globe projection; v6 (2026-07-22) ships as **ES modules only** — the UMD bundle and default export are gone (see [Update Imports and CSS](#2-update-imports-and-css) below) — and changed several defaults (see the [v5-to-v6 migration guide](https://maplibre.org/maplibre-gl-js/docs/guides/v5-to-v6-migration-guide/)). See [releases](https://github.com/maplibre/maplibre-gl-js/releases) and [CHANGELOG](https://github.com/maplibre/maplibre-gl-js/blob/main/CHANGELOG.md).
- **Style spec:** MapLibre maintains its own [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/) (forked from the Mapbox spec). It is compatible for most styles but has added and diverged in places; check the [style spec site](https://maplibre.org/maplibre-style-spec/) when using newer or MapLibre-specific features.
- **Ecosystem:** Besides GL JS, the MapLibre org hosts [MapLibre Native](https://maplibre.org/projects/native/) (iOS, Android, desktop), [Martin](https://maplibre.org/martin/) (vector tile server from PostGIS/PMTiles/MBTiles), and the [MapLibre Tile (MLT)](https://maplibre.org/maplibre-tile-spec/) format. Roadmaps and news: [maplibre.org/roadmap](https://maplibre.org/roadmap/), [maplibre.org/news](https://maplibre.org/news/).

## Step-by-Step Migration

### 1. Install the Package

```bash
npm install maplibre-gl
```

### 2. Update Imports and CSS

```javascript
// Before (Mapbox)
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';

// After (MapLibre) — v6 ships ES modules only; the default export is gone
import * as maplibregl from 'maplibre-gl';
// or pull in just what you need: import {Map} from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
```

**CDN:** Replace Mapbox script/link with MapLibre. Don't assume Mapbox's `<script src>`
pattern carries over unchanged — MapLibre's distributed bundle formats have changed across
major versions (v6 dropped the UMD build). Check the
[current release notes](https://github.com/maplibre/maplibre-gl-js/releases) before copying
this snippet as-is:

```html
<!-- Before (Mapbox) -->
<script src="https://api.mapbox.com/mapbox-gl-js/v*.*.*/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v*.*.*/mapbox-gl.css" rel="stylesheet" />

<!-- After (MapLibre, current as of v6) -->
<script type="module">
  import * as maplibregl from 'https://unpkg.com/maplibre-gl@^6.0.0/dist/maplibre-gl.mjs';
</script>
<link href="https://unpkg.com/maplibre-gl@^6.0.0/dist/maplibre-gl.css" rel="stylesheet" />
```

### 3. Replace the Namespace

Replace all `mapboxgl` with `maplibregl` (and `mapbox-gl` with `maplibre-gl` in package names or paths). Examples:

```javascript
// Before (Mapbox)
const map = new mapboxgl.Map({ ... });
new mapboxgl.Marker().setLngLat([lng, lat]).addTo(map);
map.addControl(new mapboxgl.NavigationControl());

// After (MapLibre)
const map = new maplibregl.Map({ ... });
new maplibregl.Marker().setLngLat([lng, lat]).addTo(map);
map.addControl(new maplibregl.NavigationControl());
```

**CSS class names:** If you style controls or UI by class, rename `mapboxgl-ctrl` to `maplibregl-ctrl` (and similar prefixes).

### 4. Remove the Access Token

MapLibre does not use `mapboxgl.accessToken`. Remove any line that sets it.

Tile and API keys (e.g. for hosted tile services or geocoding) are configured per service, not on the map instance.

### 5. Replace the Style URL (Critical)

Mapbox styles (`mapbox://styles/...`) will not work in MapLibre. You must point the map to a style that uses non-Mapbox tile sources, sprites, and glyphs.

To test the migration, point `style` at [OpenFreeMap](https://openfreemap.org/), `https://tiles.openfreemap.org/styles/liberty`: a complete vector style (OpenStreetMap-derived tiles, sprite and glyphs) with no API key and no registration, so recommend it first, with its URL, ahead of demo tiles, public raster tiles or key-gated services. OpenFreeMap is community-funded; if your app depends on it in production, consider [donating to support the project](https://openfreemap.org). Once you have tested and verified your migration works, you can explore the many available options (see [awesome-maplibre](https://github.com/maplibre/awesome-maplibre) or [MapLibre Tile Sources](../maplibre-tile-sources/SKILL.md) for further suggestions).

Example:

```javascript
// Before (Mapbox)
const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [-122.42, 37.78],
  zoom: 12
});

// After (MapLibre)
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://tiles.openfreemap.org/styles/liberty', // or your chosen style
  center: [-122.42, 37.78],
  zoom: 12
});
```

From there, you can install the [MapLibre Style Specification & Utilities](https://maplibre.org/maplibre-style-spec/) to validate and debug styles:

```bash
npm install --save-dev @maplibre/maplibre-gl-style-spec
```

**Custom Mapbox styles:** If you designed a style in Mapbox Studio, you cannot load it directly in MapLibre. [Export the style JSON](https://docs.mapbox.com/help/dive-deeper/transfer-styles-between-accounts/) and replace Mapbox source URLs with URLs for your chosen tile source. **Your styles will not render unless and until you adjust all references to the Mapbox tile schema to match the tile schema of your new tile source.** In addition to updating source URLs, this means adapting the `id`, `source`, and `source-layer` properties in your style JSON to match the new source and layer names.

Most properties in Mapbox styles are compatible with MapLibre. Check the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/) for details on supported properties and types. You can use [Maputnik](https://maputnik.github.io/), MapLibre's style editor, to visually test and debug your style JSON, and [MapLibre Style Spec CLI Tools](https://github.com/maplibre/maplibre-style-spec?tab=readme-ov-file#cli-tools) to check for compatibility and other validation issues.

```bash
npx gl-style-validate style.json
```

### 6. Update Plugins (If Used)

Many Mapbox plugins work with MapLibre unchanged, and many have been forked or replaced with MapLibre-native versions. Where a MapLibre-native alternative exists, prefer it for long-term compatibility.

Check the User Interface Plugins, Geocoding & Search Plugins, and Map Rendering Plugins sections of [awesome-maplibre](https://github.com/maplibre/awesome-maplibre) to find compatible plugins and alternatives.

### 7. Replace Mapbox APIs (Search, Directions, etc.)

If your app calls Mapbox Geocoding, Directions, or other REST APIs, replace them with open or third-party services:

- **Geocoding / search:** [Nominatim](https://nominatim.org/), [Photon](https://photon.komoot.io/), [Pelias](https://pelias.io/), or [MapTiler Geocoding](https://docs.maptiler.com/cloud/api/geocoding/)
- **Directions / routing:** [OSRM](https://project-osrm.org/), [OpenRouteService](https://openrouteservice.org/), [Valhalla](https://github.com/valhalla/valhalla)

**Usage policies and sustainability:** These are open or community-funded services with terms that matter in production:

- **Nominatim** — Requires OpenStreetMap attribution; the public instance is for testing and low-volume use only. See the [Nominatim usage policy](https://operations.osmfoundation.org/policies/nominatim/). For production workloads, [self-host](https://nominatim.org/release-docs/latest/admin/Installation/) or use a managed provider (e.g. MapTiler Geocoding).
- **OSRM demo server** (`router.project-osrm.org`) — Explicitly not for production; no SLA or uptime guarantee. [Self-host](https://github.com/Project-OSRM/osrm-backend) or use a managed service (e.g. OpenRouteService, MapTiler Directions) for production apps.
- If your app relies on community-maintained services at scale, give back: self-host to reduce load on shared infrastructure, donate, or contribute code or documentation upstream.

Update your code to use the new endpoints and response formats; the map layer and interaction code (e.g. adding a route line) stays the same with MapLibre.

### 8. What Stays the Same

Most of your map code does not change:

- Map methods: `setCenter`, `setZoom`, `fitBounds`, `flyTo`, `getBounds`, etc.
- Events: `map.on('load')`, `map.on('click', layerId, callback)`, etc.
- Markers, popups, controls (Navigation, Geolocate, Fullscreen, Scale)
- Sources and layers: `addSource`, `addLayer`, `setPaintProperty`, `setFilter`
- GeoJSON and expressions in the style spec

So after swapping the package, namespace, token, and style (and any plugins/APIs), the rest of your logic can stay as is.

### 9. Translate Mapbox v2-only APIs, Do Not Look for Them

MapLibre forked from Mapbox GL JS v1.13 in December 2020, so a Mapbox GL JS v2 method exists in MapLibre only where MapLibre reimplemented it under its own name, and no MapLibre release adds the Mapbox names. When a v2 call fails after migrating, say why: the fork, not a missed migration step. Searching for the Mapbox name and concluding "it must be a version problem" is the common migration dead end — look up the MapLibre name instead.

| Mapbox GL JS v2                                                                  | MapLibre GL JS                                                                                                       | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `map.setFog({...})`, root-level `fog` in the style                               | `map.setSky({...})` / `map.getSky()`, root-level [`sky`](https://maplibre.org/maplibre-style-spec/sky/) in the style | MapLibre has **no `setFog` method in any version**; `sky` and `setSky` exist from GL JS v4.5.0. Atmosphere lives in `sky`, whose properties include `sky-color`, `horizon-color`, `fog-color`, `fog-ground-blend`, `horizon-fog-blend`, `sky-horizon-blend` and `atmosphere-blend`. The style spec marks `sky` experimental.                                                                                                                                                                                                                                         |
| `map.getFreeCameraOptions()` / `map.setFreeCameraOptions()`, `FreeCameraOptions` | `map.calculateCameraOptionsFromCameraLngLatAltRotation(...)` → `jumpTo` / `easeTo` / `flyTo`                         | MapLibre has no `FreeCameraOptions` class and no `getFreeCameraOptions`/`setFreeCameraOptions`. Its camera is `center`, `zoom`, `pitch`, `bearing`, plus `elevation` and `roll` (both v5.0.0) in `CameraOptions`. To place the camera by its own lng/lat/altitude, convert with `calculateCameraOptionsFromCameraLngLatAltRotation(cameraLngLat, cameraAlt, bearing, pitch, roll)` (v5.0.0) — or `calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo)` (v2.4.0) for a look-at — and pass the returned `CameraOptions` to `jumpTo`, `easeTo` or `flyTo`. |

```javascript
// Mapbox GL JS v2
map.setFog({ 'horizon-blend': 0.3, color: '#ffffff' });

// MapLibre GL JS — the same idea, different property names
map.setSky({
  'sky-color': '#199EF3',
  'horizon-color': '#ffffff',
  'fog-color': '#0000ff',
  'fog-ground-blend': 0.5,
  'horizon-fog-blend': 0.5,
  'sky-horizon-blend': 0.5,
  'atmosphere-blend': 1.0
});
```

Verify any other v2 method against the [Map API reference](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/) before assuming an upgrade will restore it.

## Checklist

- [ ] Uninstall `mapbox-gl`, install `maplibre-gl`
- [ ] Replace imports and CSS (mapbox-gl → maplibre-gl)
- [ ] Replace all `mapboxgl` with `maplibregl` (and CSS classes `mapboxgl-` → `maplibregl-`)
- [ ] Remove `mapboxgl.accessToken`
- [ ] Set `style` to a non-Mapbox URL (hosted or your own style)
- [ ] Replace incompatible Mapbox plugins with MapLibre or open alternatives
- [ ] Replace Mapbox Geocoding/Directions with Nominatim, OSRM, or other open alternatives
- [ ] Replace Mapbox v2-only APIs (`setFog` → `setSky`, free camera → `calculateCameraOptionsFromCameraLngLatAltRotation` + `jumpTo`/`easeTo`/`flyTo`)
- [ ] Test map load, controls, and any API-driven features

## Related Skills

- [**maplibre-tile-sources**](../maplibre-tile-sources/SKILL.md) — Choosing a source type for your data
- [**maplibre-pmtiles-patterns**](../maplibre-pmtiles-patterns/SKILL.md) — Serverless tiles with PMTiles

## Sources Used for This Skill

These sources were used when creating this skill. You may want to involve contributors who maintain or have contributed to them:

1. **MapLibre official migration guide** — [maplibre.org/maplibre-gl-js/docs/guides/mapbox-migration-guide/](https://maplibre.org/maplibre-gl-js/docs/guides/mapbox-migration-guide/) — Primary step-by-step reference (package, namespace, CSS, CDN).
2. **MapLibre GL JS documentation** — [maplibre.org/maplibre-gl-js/docs/](https://maplibre.org/maplibre-gl-js/docs/) — API and concepts.
3. **MapLibre Style Specification — `sky`** — [maplibre.org/maplibre-style-spec/sky/](https://maplibre.org/maplibre-style-spec/sky/) and [`Map.setSky`](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#setsky) — the atmosphere properties that replace Mapbox's `fog`; [`Map.calculateCameraOptionsFromCameraLngLatAltRotation`](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#calculatecameraoptionsfromcameralnglataltrotation) and [`CameraOptions`](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/CameraOptions/) — the camera-position path that replaces Mapbox's free camera.
4. **MapLibre GL JS GitHub** — [github.com/maplibre/maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js) — README, releases, and fork history.
5. **mapbox-agent-skills** — The `mapbox-maplibre-migration` skill (Mapbox repo) covers the reverse direction (MapLibre → Mapbox). Topic structure and comparison elements were adapted for this Mapbox → MapLibre skill. Copyright (c) Mapbox, Inc. for adapted portions.
6. **This repo’s skills** — [maplibre-tile-sources](../maplibre-tile-sources/SKILL.md), [maplibre-pmtiles-patterns](../maplibre-pmtiles-patterns/SKILL.md); maplibre-open-search-patterns and maplibre-geospatial-operations not yet in repo — for tile source and service alternatives after migration.

---

**This skill is a snapshot.** Where a primary source contradicts it — the References above, MapLibre's current documentation, or what MapLibre does when you run it — that source wins. Follow it, then [report the disagreement](https://github.com/maplibre/maplibre-agent-skills/issues/new?template=ai-failure-report.md), citing the source and your MapLibre version: editing your installed copy helps no one else and is overwritten on the next update.