← MapboxCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Mapbox
Snapshot Sep 30, 2026 · 23:11 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "mapbox-google-maps-migration",
"description": "Migration guide for developers moving from Google Maps Platform to Mapbox GL JS, covering API equivalents, pattern translations, and key differences",
"included_files": [
{
"relative_path": "AGENTS.md",
"size_in_bytes": 8730
},
{
"relative_path": "evals/evals.json",
"size_in_bytes": 2790
},
{
"relative_path": "references/api-services.md",
"size_in_bytes": 3767
},
{
"relative_path": "references/clustering-styling.md",
"size_in_bytes": 2684
},
{
"relative_path": "references/data-performance.md",
"size_in_bytes": 1972
},
{
"relative_path": "references/directions-controls.md",
"size_in_bytes": 1968
},
{
"relative_path": "references/shapes-geocoding.md",
"size_in_bytes": 3963
}
],
"skill_md_contents": "---\nname: mapbox-google-maps-migration\ndescription: Migration guide for developers moving from Google Maps Platform to Mapbox GL JS, covering API equivalents, pattern translations, and key differences\n---\n\n# Mapbox Google Maps Migration Skill\n\nComprehensive guidance for migrating from Google Maps Platform to Mapbox GL JS. Provides API equivalents, pattern translations, and strategies for successful migration.\n\n## Core Philosophy Differences\n\n### Google Maps: Imperative & Object-Oriented\n\n- Create objects (Marker, Polygon, etc.)\n- Add to map with `.setMap(map)`\n- Update properties with setters\n- Heavy reliance on object instances\n\n### Mapbox GL JS: Declarative & Data-Driven\n\n- Add data sources\n- Define layers (visual representation)\n- Style with JSON\n- Update data, not object properties\n\n**Key Insight:** Mapbox treats everything as data + styling, not individual objects.\n\n## Map Initialization\n\n### Google Maps\n\n```javascript\nconst map = new google.maps.Map(document.getElementById('map'), {\n center: { lat: 37.7749, lng: -122.4194 },\n zoom: 12,\n mapTypeId: 'roadmap' // or 'satellite', 'hybrid', 'terrain'\n});\n```\n\n### Mapbox GL JS\n\n```javascript\nmapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN';\nconst map = new mapboxgl.Map({\n container: 'map',\n style: 'mapbox://styles/mapbox/streets-v12', // or satellite-v9, outdoors-v12\n center: [-122.4194, 37.7749], // [lng, lat] - note the order!\n zoom: 12\n});\n```\n\n**Key Differences:**\n\n- **Coordinate order:** Google uses `{lat, lng}`, Mapbox uses `[lng, lat]`\n- **Authentication:** Google uses API key in script tag, Mapbox uses access token in code\n- **Styling:** Google uses map types, Mapbox uses full style URLs\n\n## API Equivalents Reference\n\n### Map Methods\n\n| Google Maps | Mapbox GL JS | Notes |\n| ------------------------ | -------------------------------------- | ----------------------------- |\n| `map.setCenter(latLng)` | `map.setCenter([lng, lat])` | Coordinate order reversed |\n| `map.getCenter()` | `map.getCenter()` | Returns LngLat object |\n| `map.setZoom(zoom)` | `map.setZoom(zoom)` | Same behavior |\n| `map.getZoom()` | `map.getZoom()` | Same behavior |\n| `map.panTo(latLng)` | `map.panTo([lng, lat])` | Animated pan |\n| `map.fitBounds(bounds)` | `map.fitBounds([[lng,lat],[lng,lat]])` | Different bound format |\n| `map.setMapTypeId(type)` | `map.setStyle(styleUrl)` | Completely different approach |\n| `map.getBounds()` | `map.getBounds()` | Similar |\n\n### Map Events\n\n| Google Maps | Mapbox GL JS | Notes |\n| ------------------------------------------------- | ---------------------- | --------------------- |\n| `google.maps.event.addListener(map, 'click', fn)` | `map.on('click', fn)` | Simpler syntax |\n| `event.latLng` | `event.lngLat` | Event property name |\n| `'center_changed'` | `'move'` / `'moveend'` | Different event names |\n| `'zoom_changed'` | `'zoom'` / `'zoomend'` | Different event names |\n| `'bounds_changed'` | `'moveend'` | No direct equivalent |\n| `'mousemove'` | `'mousemove'` | Same |\n| `'mouseout'` | `'mouseleave'` | Different name |\n\n## Markers and Points\n\n### Simple Marker\n\n**Google Maps:**\n\n```javascript\nconst marker = new google.maps.Marker({\n position: { lat: 37.7749, lng: -122.4194 },\n map: map,\n title: 'San Francisco',\n icon: 'custom-icon.png'\n});\n\n// Remove marker\nmarker.setMap(null);\n```\n\n**Mapbox GL JS:**\n\n```javascript\n// Create marker\nconst marker = new mapboxgl.Marker()\n .setLngLat([-122.4194, 37.7749])\n .setPopup(new mapboxgl.Popup().setText('San Francisco'))\n .addTo(map);\n\n// Remove marker\nmarker.remove();\n```\n\n### Multiple Markers\n\n**Google Maps:**\n\n```javascript\nconst markers = locations.map(\n (loc) =>\n new google.maps.Marker({\n position: { lat: loc.lat, lng: loc.lng },\n map: map\n })\n);\n```\n\n**Mapbox GL JS (Equivalent Approach):**\n\n```javascript\n// Same object-oriented approach\nconst markers = locations.map((loc) => new mapboxgl.Marker().setLngLat([loc.lng, loc.lat]).addTo(map));\n```\n\n**Mapbox GL JS (Data-Driven Approach - Recommended for 100+ points):**\n\n```javascript\n// Add as GeoJSON source + layer (uses WebGL, not DOM)\nmap.addSource('points', {\n type: 'geojson',\n data: {\n type: 'FeatureCollection',\n features: locations.map((loc) => ({\n type: 'Feature',\n geometry: { type: 'Point', coordinates: [loc.lng, loc.lat] },\n properties: { name: loc.name }\n }))\n }\n});\n\nmap.addLayer({\n id: 'points-layer',\n type: 'circle', // or 'symbol' for icons\n source: 'points',\n paint: {\n 'circle-radius': 8,\n 'circle-color': '#ff0000'\n }\n});\n```\n\n**Performance Advantage:** Google Maps renders all markers as DOM elements (even when using the Data Layer), which becomes slow with 500+ markers. Mapbox's circle and symbol layers are rendered by WebGL, making them much faster for large datasets (1,000-10,000+ points). This is a significant advantage when building applications with many points.\n\n## Info Windows / Popups\n\n### Google Maps\n\n```javascript\nconst infowindow = new google.maps.InfoWindow({\n content: '<h3>Title</h3><p>Content</p>'\n});\n\nmarker.addListener('click', () => {\n infowindow.open(map, marker);\n});\n```\n\n### Mapbox GL JS\n\n```javascript\n// Option 1: Attach to marker\nconst marker = new mapboxgl.Marker()\n .setLngLat([-122.4194, 37.7749])\n .setPopup(new mapboxgl.Popup().setHTML('<h3>Title</h3><p>Content</p>'))\n .addTo(map);\n\n// Option 2: On layer click (for data-driven markers)\nmap.on('click', 'points-layer', (e) => {\n const coordinates = e.features[0].geometry.coordinates.slice();\n const description = e.features[0].properties.description;\n\n new mapboxgl.Popup().setLngLat(coordinates).setHTML(description).addTo(map);\n});\n```\n\n## Migration Strategy\n\n### Step 1: Audit Current Implementation\n\nIdentify all Google Maps features you use:\n\n- [ ] Basic map with markers\n- [ ] Info windows/popups\n- [ ] Polygons/polylines\n- [ ] Geocoding\n- [ ] Directions\n- [ ] Clustering\n- [ ] Custom styling\n- [ ] Drawing tools\n- [ ] Street View (no Mapbox equivalent)\n- [ ] Other advanced features\n\n### Step 2: Set Up Mapbox\n\n```html\n<!-- Replace Google Maps script -->\n<script src=\"https://api.mapbox.com/mapbox-gl-js/v3.18.1/mapbox-gl.js\"></script>\n<link href=\"https://api.mapbox.com/mapbox-gl-js/v3.18.1/mapbox-gl.css\" rel=\"stylesheet\" />\n```\n\n### Step 3: Convert Core Map\n\nStart with basic map initialization:\n\n1. Replace `new google.maps.Map()` with `new mapboxgl.Map()`\n2. Fix coordinate order (lat,lng -> lng,lat)\n3. Update zoom/center\n\n### Step 4: Convert Features One by One\n\nPrioritize by complexity:\n\n1. **Easy:** Map controls, basic markers\n2. **Medium:** Popups, polygons, lines\n3. **Complex:** Clustering, custom styling, data updates\n\n### Step 5: Update Event Handlers\n\nChange event syntax:\n\n- `google.maps.event.addListener()` -> `map.on()`\n- Update event property names (`latLng` -> `lngLat`)\n\n### Step 6: Optimize for Mapbox\n\nTake advantage of Mapbox features:\n\n- Convert multiple markers to data-driven layers\n- Use clustering (built-in)\n- Leverage vector tiles for custom styling\n- Use expressions for dynamic styling\n\n### Step 7: Test Thoroughly\n\n- Cross-browser testing\n- Mobile responsiveness\n- Performance with real data volumes\n- Touch/gesture interactions\n\n## Gotchas and Common Issues\n\n### Coordinate Order\n\n```javascript\n// Google Maps\n{ lat: 37.7749, lng: -122.4194 }\n\n// Mapbox (REVERSED!)\n[-122.4194, 37.7749]\n```\n\n**Always double-check coordinate order!**\n\n### Event Properties\n\n```javascript\n// Google Maps\nmap.on('click', (e) => {\n console.log(e.latLng.lat(), e.latLng.lng());\n});\n\n// Mapbox\nmap.on('click', (e) => {\n console.log(e.lngLat.lat, e.lngLat.lng);\n});\n```\n\n### Timing Issues\n\n```javascript\n// Google Maps - immediate\nconst marker = new google.maps.Marker({ map: map });\n\n// Mapbox - wait for load\nmap.on('load', () => {\n map.addSource(...);\n map.addLayer(...);\n});\n```\n\n### Removing Features\n\n```javascript\n// Google Maps\nmarker.setMap(null);\n\n// Mapbox - must remove both\nmap.removeLayer('layer-id');\nmap.removeSource('source-id');\n```\n\n### Updating Data Without Flash\n\n**Never** remove and re-add layers to update data — this reinitializes WebGL resources and causes a visible flash. Instead:\n\n```javascript\n// ✅ Update data in place (no flash)\nmap.getSource('stores').setData(newGeoJSON);\n\n// ✅ Filter existing data (GPU-side, fastest)\nmap.setFilter('stores-layer', ['==', ['get', 'category'], 'coffee']);\n\n// ❌ BAD: remove + re-add causes flash\nmap.removeLayer('stores-layer');\nmap.removeSource('stores');\nmap.addSource('stores', { ... });\nmap.addLayer({ ... });\n```\n\n## When NOT to Migrate\n\nConsider staying with Google Maps if:\n\n- **Street View is critical** - Mapbox doesn't have equivalent\n- **Tight Google Workspace integration** - Places API deeply integrated\n- **Already heavily optimized** - Migration cost > benefits\n- **Team expertise** - Retraining costs too high\n- **Short-term project** - Not worth migration effort\n\n## Quick Reference: Side-by-Side Comparison\n\n```javascript\n// GOOGLE MAPS\nconst map = new google.maps.Map(el, {\n center: { lat: 37.7749, lng: -122.4194 },\n zoom: 12\n});\n\nconst marker = new google.maps.Marker({\n position: { lat: 37.7749, lng: -122.4194 },\n map: map\n});\n\ngoogle.maps.event.addListener(map, 'click', (e) => {\n console.log(e.latLng.lat(), e.latLng.lng());\n});\n\n// MAPBOX GL JS\nmapboxgl.accessToken = 'YOUR_TOKEN';\nconst map = new mapboxgl.Map({\n container: el,\n center: [-122.4194, 37.7749], // REVERSED!\n zoom: 12,\n style: 'mapbox://styles/mapbox/streets-v12'\n});\n\nconst marker = new mapboxgl.Marker()\n .setLngLat([-122.4194, 37.7749]) // REVERSED!\n .addTo(map);\n\nmap.on('click', (e) => {\n console.log(e.lngLat.lat, e.lngLat.lng);\n});\n```\n\n**Remember:** lng, lat order in Mapbox!\n\n## Additional Resources\n\n- [Mapbox GL JS Documentation](https://docs.mapbox.com/mapbox-gl-js/)\n- [Official Google Maps to Mapbox Migration Guide](https://docs.mapbox.com/help/tutorials/google-to-mapbox/)\n- [Mapbox Examples](https://docs.mapbox.com/mapbox-gl-js/examples/)\n- [Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/)\n\n## Integration with Other Skills\n\n**Works with:**\n\n- **mapbox-web-integration-patterns**: Framework-specific migration guidance\n- **mapbox-web-performance-patterns**: Optimize after migration\n- **mapbox-token-security**: Secure your Mapbox tokens properly\n- **mapbox-geospatial-operations**: Use Mapbox's geospatial tools effectively\n- **mapbox-search-patterns**: Migrate geocoding/search functionality\n\n## Reference Files\n\nThe following reference files contain detailed migration guides for specific topics. Load them when working on those areas:\n\n- **`references/shapes-geocoding.md`** — Polygons, Polylines, Custom Icons, Geocoding\n- **`references/directions-controls.md`** — Directions/Routing, Controls\n- **`references/clustering-styling.md`** — Clustering, Styling/Appearance\n- **`references/data-performance.md`** — Data Updates, Performance, Common Migration Patterns (Store Locator, Drawing Tools, Heatmaps)\n- **`references/api-services.md`** — API Services Comparison, Pricing, Plugins, Framework Integration, Testing, Migration Checklist\n\nTo load a reference, read the file relative to this skill directory, e.g.:\n\n```\nLoad references/shapes-geocoding.md\n```\n"
}SHA-256: 428686531c851c9abb193a4f50138172252e9b8a1c50e868d291d072e4a81bd3