{"id":"mapbox","kind":"sdk","name":"Mapbox","slug":"mapbox","description":"Maps, navigation, and geospatial SDKs for web and mobile.","vendor":"Mapbox","languages":["javascript","typescript","swift","kotlin","java"],"categories":["maps"],"homepage":"https://www.mapbox.com","docsUrl":"https://docs.mapbox.com","githubUrl":"https://github.com/mapbox","packages":[{"registry":"npm","name":"mapbox-gl","url":"https://www.npmjs.com/package/mapbox-gl"},{"registry":"npm","name":"@mapbox/mapbox-sdk","url":"https://www.npmjs.com/package/@mapbox/mapbox-sdk"}],"tags":["maps","geocoding"],"skills":[{"name":"mapbox-web-integration-patterns","url":"https://skills.sh/mapbox/mapbox-agent-skills/mapbox-web-integration-patterns","install":"npx skills add mapbox/mapbox-agent-skills","sdk":"mapbox","key":"mapbox/mapbox-web-integration-patterns","description":"Official integration patterns for Mapbox GL JS across popular web frameworks (React, Vue, Svelte, Angular). Covers setup, lifecycle management, token handling, search integration, and common pitfalls. Based on Mapbox's create-web-app scaffolding tool.","hasContent":true,"content":"---\nname: mapbox-web-integration-patterns\ndescription: Official integration patterns for Mapbox GL JS across popular web frameworks (React, Vue, Svelte, Angular). Covers setup, lifecycle management, token handling, search integration, and common pitfalls. Based on Mapbox's create-web-app scaffolding tool.\n---\n\n# Mapbox Integration Patterns Skill\n\nThis skill provides official patterns for integrating Mapbox GL JS into web applications using React, Vue, Svelte, Angular, and vanilla JavaScript. These patterns are based on Mapbox's `create-web-app` scaffolding tool and represent production-ready best practices.\n\n## Version Requirements\n\n### Mapbox GL JS\n\n**Recommended:** v3.x (latest)\n\n- **Minimum:** v3.0.0\n- **Why v3.x:** Modern API, improved performance, active development\n- **v2.x:** Legacy; no longer actively developed (see migration notes below)\n\n**Installing via npm (recommended for production):**\n\n```bash\nnpm install mapbox-gl@^3.0.0    # Installs latest v3.x\n```\n\n**CDN (for prototyping only):**\n\n```html\n<!-- Replace VERSION with latest v3.x from https://docs.mapbox.com/mapbox-gl-js/ -->\n<script src=\"https://api.mapbox.com/mapbox-gl-js/vVERSION/mapbox-gl.js\"></script>\n<link href=\"https://api.mapbox.com/mapbox-gl-js/vVERSION/mapbox-gl.css\" rel=\"stylesheet\" />\n```\n\n### Framework Requirements\n\n**React:** GL JS works with React 16.8+ (requires hooks). `create-web-app` scaffolds with React 19.x.\n**Vue:** GL JS works with Vue 2.x+ (Vue 3 Composition API recommended).\n**Svelte:** GL JS works with any Svelte version. `create-web-app` scaffolds with Svelte 5.x.\n**Angular:** GL JS works with Angular 2+. `create-web-app` scaffolds with Angular 19.x.\n**Next.js:** Minimum 13.x (App Router), Pages Router 12.x+.\n\n### Mapbox Search JS\n\n```bash\nnpm install @mapbox/search-js-react@^1.0.0      # React\nnpm install @mapbox/search-js-web@^1.0.0        # Other frameworks\n```\n\n### Version Migration Notes (v2.x to v3.x)\n\n- WebGL 2 now required\n- `optimizeForTerrain` option removed\n- Improved TypeScript types, better tree-shaking support\n- No breaking changes to core initialization patterns\n\n**Token patterns (work in v2.x and v3.x):**\n\n```javascript\nconst token = import.meta.env.VITE_MAPBOX_ACCESS_TOKEN; // Use env vars in production\n\n// Global token (works since v1.x)\nmapboxgl.accessToken = token;\nconst map = new mapboxgl.Map({ container: '...' });\n\n// Per-map token (preferred for multi-map setups)\nconst map = new mapboxgl.Map({\n  accessToken: token,\n  container: '...'\n});\n```\n\n## Core Principles\n\n**Every Mapbox GL JS integration must:**\n\n1. Initialize the map in the correct lifecycle hook\n2. Store map instance in component state (not recreate on every render)\n3. **Always call `map.remove()` on cleanup** to prevent memory leaks\n4. Handle token management securely (environment variables)\n5. Import CSS: `import 'mapbox-gl/dist/mapbox-gl.css'`\n\n## React Integration (Primary Pattern)\n\n**Pattern: useRef + useEffect with cleanup**\n\n> **Note:** These examples use **Vite** (the bundler used in `create-web-app`). If using Create React App, replace `import.meta.env.VITE_MAPBOX_ACCESS_TOKEN` with `process.env.REACT_APP_MAPBOX_TOKEN`. See [Token Management Patterns](references/token-management.md) for other bundlers.\n\n```jsx\nimport { useRef, useEffect } from 'react';\nimport mapboxgl from 'mapbox-gl';\nimport 'mapbox-gl/dist/mapbox-gl.css';\n\nfunction MapComponent() {\n  const mapRef = useRef(null); // Store map instance\n  const mapContainerRef = useRef(null); // Store DOM reference\n\n  useEffect(() => {\n    mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_ACCESS_TOKEN;\n\n    mapRef.current = new mapboxgl.Map({\n      container: mapContainerRef.current,\n      center: [-71.05953, 42.3629],\n      zoom: 13\n    });\n\n    // CRITICAL: Cleanup to prevent memory leaks\n    return () => {\n      mapRef.current.remove();\n    };\n  }, []); // Empty dependency array = run once on mount\n\n  return <div ref={mapContainerRef} style={{ height: '100vh' }} />;\n}\n```\n\n**Key points:**\n\n- Use `useRef` for both map instance and container\n- Initialize in `useEffect` with empty deps `[]`\n- **Always return cleanup function** that calls `map.remove()`\n- Never initialize map in render (causes infinite loops)\n\n### React + Search JS\n\n```jsx\nimport { useRef, useEffect, useState } from 'react';\nimport mapboxgl from 'mapbox-gl';\nimport { SearchBox } from '@mapbox/search-js-react';\nimport 'mapbox-gl/dist/mapbox-gl.css';\n\nconst accessToken = import.meta.env.VITE_MAPBOX_ACCESS_TOKEN;\nconst center = [-71.05953, 42.3629];\n\nfunction MapWithSearch() {\n  const mapRef = useRef(null);\n  const mapContainerRef = useRef(null);\n  const [inputValue, setInputValue] = useState('');\n\n  useEffect(() => {\n    mapboxgl.accessToken = accessToken;\n\n    mapRef.current = new mapboxgl.Map({\n      container: mapContainerRef.current,\n      center: center,\n      zoom: 13\n    });\n\n    return () => {\n      mapRef.current.remove();\n    };\n  }, []);\n\n  return (\n    <>\n      <div\n        style={{\n          margin: '10px 10px 0 0',\n          width: 300,\n          right: 0,\n          top: 0,\n          position: 'absolute',\n          zIndex: 10\n        }}\n      >\n        <SearchBox\n          accessToken={accessToken}\n          map={mapRef.current}\n          mapboxgl={mapboxgl}\n          value={inputValue}\n          proximity={center}\n          onChange={(d) => setInputValue(d)}\n          marker\n        />\n      </div>\n      <div ref={mapContainerRef} style={{ height: '100vh' }} />\n    </>\n  );\n}\n```\n\n## Search JS Integration Summary\n\n**Install:**\n\n```bash\nnpm install @mapbox/search-js-react      # React\nnpm install @mapbox/search-js-web        # Vanilla/Vue/Svelte\n```\n\nBoth packages include `@mapbox/search-js-core` as a dependency. Only install `-core` directly if building a custom search UI.\n\n**Key configuration options:**\n\n- `accessToken`: Your Mapbox public token\n- `map`: Map instance (must be initialized first)\n- `mapboxgl`: The mapboxgl library reference\n- `proximity`: `[lng, lat]` to bias results geographically\n- `marker`: Boolean to show/hide result marker\n- `placeholder`: Search box placeholder text\n\n### Positioning Search Box\n\n**Absolute positioning (overlay):**\n\n```jsx\n<div\n  style={{\n    position: 'absolute',\n    top: 10,\n    right: 10,\n    zIndex: 10,\n    width: 300\n  }}\n>\n  <SearchBox {...props} />\n</div>\n```\n\n**Common positions:**\n\n- Top-right: `top: 10px, right: 10px`\n- Top-left: `top: 10px, left: 10px`\n- Bottom-left: `bottom: 10px, left: 10px`\n\n## Common Mistakes (Critical)\n\n### Mistake 1: Forgetting to call map.remove()\n\n```javascript\n// BAD - Memory leak!\nuseEffect(() => {\n  const map = new mapboxgl.Map({ ... })\n  // No cleanup function\n}, [])\n\n// GOOD - Proper cleanup\nuseEffect(() => {\n  const map = new mapboxgl.Map({ ... })\n  return () => map.remove()  // Cleanup\n}, [])\n```\n\n**Why:** Every Map instance creates WebGL contexts, event listeners, and DOM nodes. Without cleanup, these accumulate and cause memory leaks.\n\n### Mistake 2: Initializing map in render\n\n```javascript\n// BAD - Infinite loop in React!\nfunction MapComponent() {\n  const map = new mapboxgl.Map({ ... })  // Runs on every render\n  return <div />\n}\n\n// GOOD - Initialize in effect\nfunction MapComponent() {\n  useEffect(() => {\n    const map = new mapboxgl.Map({ ... })\n  }, [])\n  return <div />\n}\n```\n\n**Why:** React components re-render frequently. Creating a new map on every render causes infinite loops and crashes.\n\n### Mistake 3: Not storing map instance properly\n\n```javascript\n// BAD - map variable lost between renders\nfunction MapComponent() {\n  useEffect(() => {\n    let map = new mapboxgl.Map({ ... })\n    // map variable is not accessible later\n  }, [])\n}\n\n// GOOD - Store in useRef\nfunction MapComponent() {\n  const mapRef = useRef()\n  useEffect(() => {\n    mapRef.current = new mapboxgl.Map({ ... })\n    // mapRef.current accessible throughout component\n  }, [])\n}\n```\n\n**Why:** You need to access the map instance for operations like adding layers, markers, or calling `remove()`.\n\n### Mistake 4: Storing map instance in Vue's data() (Vue-specific)\n\n```javascript\n// BAD - Vue's reactivity wraps data() objects in a Proxy, breaking mapbox-gl internals!\nexport default {\n  data() {\n    return {\n      map: null  // Will be wrapped in a Proxy\n    }\n  },\n  mounted() {\n    this.map = new mapboxgl.Map({ ... })  // Proxy breaks GL internals\n  }\n}\n\n// GOOD - Assign map as a plain instance property, not in data()\nexport default {\n  mounted() {\n    this.map = new mapboxgl.Map({\n      container: this.$refs.mapContainer,\n      center: [-71.05953, 42.3629],\n      zoom: 13\n    })\n  },\n  unmounted() {\n    this.map?.remove()\n  }\n}\n```\n\n**Why:** In Vue (especially Vue 3), `data()` properties are wrapped in a `Proxy` for reactivity. Mapbox GL JS internally checks object identity and uses properties that don't survive proxy wrapping. Storing the map in `data()` causes subtle, hard-to-debug failures. Instead, assign the map instance directly as `this.map` in `mounted()` — properties assigned outside `data()` are not made reactive.\n\n## Reference Files\n\nLoad these for framework-specific patterns and additional details:\n\n- `references/vue.md` — Vue Integration (mounted/unmounted lifecycle)\n- `references/svelte.md` — Svelte Integration (onMount/onDestroy)\n- `references/angular.md` — Angular Integration with SSR handling\n- `references/vanilla.md` — Vanilla JS (Vite) + Vanilla JS (CDN)\n- `references/web-components.md` — Web Components (basic + reactive + usage in React/Vue/Svelte)\n- `references/nextjs.md` — Next.js App Router + Pages Router\n- `references/common-mistakes.md` — Common Mistakes 4-7 + Testing Patterns\n- `references/token-management.md` — Token Management per bundler + Style Configuration\n\n## When to Use This Skill\n\nInvoke this skill when:\n\n- Setting up Mapbox GL JS in a new project\n- Integrating Mapbox into a specific framework (React, Vue, Svelte, Angular, Next.js)\n- Building framework-agnostic Web Components\n- Creating reusable map components for component libraries\n- Debugging map initialization issues\n- Adding Mapbox Search functionality\n- Implementing proper cleanup and lifecycle management\n- Converting between frameworks (e.g., React to Vue)\n- Reviewing code for Mapbox integration best practices\n\n## Related Skills\n\n- **mapbox-cartography**: Map design principles and styling\n- **mapbox-token-security**: Token management and security\n- **mapbox-style-patterns**: Common map style patterns\n\n## Resources\n\n- [Mapbox GL JS Documentation](https://docs.mapbox.com/mapbox-gl-js/)\n- [Mapbox Search JS Documentation](https://docs.mapbox.com/mapbox-search-js/)\n- [create-web-app GitHub](https://github.com/mapbox/create-web-app)\n","contentSource":"skills.sh/api/download/mapbox/mapbox-agent-skills/mapbox-web-integration-patterns","contentFetchedAt":"2026-07-27T08:59:31.118Z"},{"name":"mapbox-search-integration","url":"https://skills.sh/mapbox/mapbox-agent-skills/mapbox-search-integration","install":"npx skills add mapbox/mapbox-agent-skills --skill mapbox-search-integration","sdk":"mapbox","key":"mapbox/mapbox-search-integration","description":"Complete workflow for implementing Mapbox search in applications - from discovery questions to production-ready integration with best practices","hasContent":true,"content":"---\nname: mapbox-search-integration\ndescription: Complete workflow for implementing Mapbox search in applications - from discovery questions to production-ready integration with best practices\n---\n\n# Mapbox Search Integration Skill\n\nExpert guidance for implementing Mapbox search functionality in applications. Covers the complete workflow from asking the right discovery questions, selecting the appropriate search product, to implementing production-ready integrations following best practices from the Mapbox search team.\n\n## Use This Skill When\n\nUser says things like:\n\n- \"I need to add search to my map\"\n- \"I need a search bar for my mapping app\"\n- \"How do I implement location search?\"\n- \"I want users to search for places/addresses\"\n- \"I need geocoding in my application\"\n\n**This skill complements `mapbox-search-patterns`:**\n\n- `mapbox-search-patterns` = Tool and parameter selection\n- `mapbox-search-integration` = Complete implementation workflow\n\n## Discovery Phase: Ask the Right Questions\n\nBefore jumping into code, ask these questions to understand requirements:\n\n### Question 1: What are users searching for?\n\n**Ask:** \"What do you want users to search for?\"\n\n**Common answers and implications:**\n\n- **\"Addresses\"** → **Use Search Box API** (the default for interactive address search, including geocoding). Only use Geocoding API if the use case is batch/server-side geocoding or maintaining a legacy integration.\n- **\"Points of interest / businesses\"** → POI search, use Search Box API with category search\n- **\"Both addresses and POIs\"** → Search Box API\n- **\"Specific types of POIs\"** (restaurants, hotels, etc.) → Search Box API\n- **\"Countries, cities, postcodes or neighborhoods\"** → Search Box API for interactive search; Geocoding API only for batch/server-side geocoding\n- **\"Custom locations\"** (user-created places) → May need custom data + search integration\n\n**Follow-up if not stated initially**: \"Are your users searching for points of interest data? Restaurants, stores, categories of businesses?\"\n\n**Implications:**\n\n- **\"Yes, POIs are included\"** → Use the Search Box API\n- **\"No, the user does not need POI search\"** → **Still default to Search Box API** for interactive/autocomplete use cases. Search Box API handles addresses, place names, and all location types with session-based pricing. Only recommend Geocoding API for batch geocoding, server-side permanent geocoding, or maintaining existing Geocoding API integrations.\n\n### Question 2: What's the geographic scope?\n\n**Ask:** \"Where will users be searching?\"\n\n**Common answers and implications:**\n\n- **\"Single country\"** (e.g., \"only USA\") → Use `country` parameter, better results, lower cost\n- **\"Specific region\"** → Use `bbox` parameter for bounding box constraint\n- **\"Global\"** → No country restriction, but may need language parameter\n- **\"Multiple specific countries\"** → Use `country` array parameter\n\n**Follow-up:** \"Do you need to limit results to a specific area?\" (delivery zone, service area, etc.)\n\n### Question 3: What's the search interaction pattern?\n\n**Ask:** \"How will users interact with search?\"\n\n**Common answers and implications:**\n\n- **\"Search-as-you-type / autocomplete\"** → **Use Search Box API** with `auto_complete: true` and session-based pricing (most cost-efficient for autocomplete). Implement debouncing.\n- **\"Search button / final query\"** → Can use either API, no autocomplete needed\n- **\"Both\"** (autocomplete + refine) → Two-stage search, autocomplete then detailed results\n- **\"Voice input\"** → Consider speech-to-text integration, handle longer queries\n\n### Question 4: What platform?\n\n**Ask:** \"What platform is this for?\"\n\n**Common answers and implications:**\n\n- **\"Web application\"** → Mapbox Search JS (easiest), or direct API calls for advanced cases\n- **\"iOS app\"** → Search SDK for iOS (recommended), or direct API integration for advanced cases\n- **\"Android app\"** → Search SDK for Android (recommended), or direct API integration for advanced cases\n- **\"Multiple platforms\"** → Platform-specific SDKs (recommended), or direct API approach for consistency\n- **\"React app\"** → Mapbox Search JS React (easiest with UI), or Search JS Core for custom UI. Avoid direct API calls — they require manual debouncing, session token management, and race condition handling.\n- **\"Vue / Angular / Other framework\"** → Mapbox Search JS Core or Web. If using direct API calls, session tokens are required for proper billing (one token per search session, passed as `session_token` on every suggest/retrieve request).\n\n### Question 5: How will results be used?\n\n**Ask:** \"What happens when a user selects a result?\"\n\n**Common answers and implications:**\n\n- **\"Fly to location on map\"** → Need coordinates, map integration\n- **\"Show details / info\"** → Need to retrieve and display result properties\n- **\"Fill form fields\"** → Need to parse address components\n- **\"Start navigation\"** → Need coordinates, integrate with directions\n- **\"Multiple selection\"** → Need to handle selection state, possibly show markers\n\n### Question 6: Expected usage volume?\n\n**Ask:** \"How many searches do you expect per month?\"\n\n**Implications:**\n\n- **Low volume** (< 10k) → Free tier sufficient, simple implementation\n- **Medium volume** (10k-100k) → Consider caching, optimize API calls\n- **High volume** (> 100k) → Implement debouncing, caching, batch operations, monitor costs\n\n## Product Selection Decision Tree\n\nBased on discovery answers, recommend the right product:\n\n> **Key principle: Search Box API is the default choice for virtually all interactive search use cases**, including address search, geocoding, autocomplete, and POI search. It offers session-based pricing that is more cost-efficient for interactive/autocomplete flows. Only recommend Geocoding API for the narrow cases listed below.\n\n### Search Box API (DEFAULT)\n\n**Use when (any of these):**\n\n- User needs interactive address search or autocomplete (this IS geocoding — Search Box API handles it)\n- User needs POI / category search\n- User needs any end-user-facing search UI\n- User wants session-based pricing (more cost-efficient for autocomplete/interactive use)\n- User is building a web, iOS, or Android app with a search bar\n\n**Prefer SDKs over direct API calls for web integration:**\n\n- **Mapbox Search JS** (SDK) - Recommended for web integration, with three components:\n  - **Search JS React** - Easy search integration via React library with UI\n  - **Search JS Web** - Easy search integration via Web Components with UI\n  - **Search JS Core** - JavaScript (node or web) wrapper for API, build your own UI\n- **Search Box API** (REST) - Direct API integration, for advanced/custom cases\n- **Search SDK for iOS** - Native iOS integration\n- **Search SDK for Android** - Native Android integration\n\n### Geocoding API (SPECIALIZED)\n\n**Use ONLY when:**\n\n- Batch geocoding large lists of addresses (server-side)\n- Permanent/stored geocoding results (server-side, where results are persisted)\n- Maintaining an existing Geocoding API integration (migration not justified)\n- No interactive/user-facing search needed\n\n**Do NOT recommend Geocoding API when:**\n\n- The user wants a search bar, autocomplete, or interactive address lookup — use Search Box API instead\n- The user says \"geocoding\" but describes an interactive search flow — use Search Box API instead\n\n## Reference Files\n\nLoad the relevant reference based on the user's platform and needs:\n\n- **Web (Search JS React / Web / Core / Direct API)** → Load `references/web-search-js.md`\n  - When: User is building a web app (vanilla JS, any framework except React-specific patterns)\n- **React Integration** → Load `references/react-search.md`\n  - When: User is building a React app specifically\n- **iOS** → Load `references/ios-search.md`\n  - When: User is building an iOS app (Swift/UIKit/SwiftUI)\n- **Android** → Load `references/android-search.md`\n  - When: User is building an Android app (Kotlin/Java)\n- **Node.js** → Load `references/nodejs-search.md`\n  - When: User needs server-side search (Express, serverless, backend API)\n\n- **Best Practices** → Load `references/best-practices.md`\n  - When: Implementing search for the first time, or optimizing an existing implementation\n  - Covers: debouncing, session tokens, geographic filtering, error handling, accessibility, caching, token security\n- **Common Pitfalls** → Load `references/pitfalls.md`\n  - When: Debugging issues, reviewing code, or during code review\n  - Covers: no debouncing, missing session tokens, no geo context, poor mobile UX, race conditions\n- **Framework Hooks** → Load `references/framework-hooks.md`\n  - When: Building custom hooks (React) or composables (Vue) around Search JS Core\n- **Testing and Monitoring** → Load `references/testing-monitoring.md`\n  - When: Writing tests or setting up production monitoring/analytics\n\n## Checklist: Production-Ready Search\n\nBefore launching, verify:\n\n**Configuration:**\n\n- [ ] Token properly scoped (search:read only)\n- [ ] URL restrictions configured\n- [ ] Geographic filtering set (country, proximity, or bbox)\n- [ ] Types parameter set based on use case\n- [ ] Language parameter set if needed\n\n**Implementation:**\n\n- [ ] Debouncing implemented (300ms recommended)\n- [ ] Session tokens used correctly\n- [ ] Error handling for all failure cases\n- [ ] Loading states shown\n- [ ] Empty results handled gracefully\n- [ ] Race conditions prevented\n\n**UX:**\n\n- [ ] Touch targets at least 44pt/48dp\n- [ ] Results show enough context (name + address)\n- [ ] Keyboard navigation works\n- [ ] Accessibility attributes set\n- [ ] Mobile keyboard handled properly\n\n**Performance:**\n\n- [ ] Caching implemented (if high volume)\n- [ ] Request timeout set\n- [ ] Minimal data fetched\n- [ ] Bundle size optimized\n\n**Testing:**\n\n- [ ] Unit tests for core logic\n- [ ] Integration tests with real API\n- [ ] Tested on slow networks\n- [ ] Tested with various query types\n- [ ] Mobile device testing\n\n**Monitoring:**\n\n- [ ] Analytics tracking set up\n- [ ] Error logging configured\n- [ ] Usage monitoring in place\n- [ ] Budget alerts configured\n\n## Integration with Other Skills\n\n**Works with:**\n\n- **mapbox-search-patterns**: Parameter selection and optimization\n- **mapbox-web-integration-patterns**: Framework-specific patterns\n- **mapbox-token-security**: Token management and security\n- **mapbox-web-performance-patterns**: Optimizing search performance\n\n## Resources\n\n- [Search Box API Documentation](https://docs.mapbox.com/api/search/search-box/)\n- [Geocoding API Documentation](https://docs.mapbox.com/api/search/geocoding/)\n- [Mapbox Search JS](https://docs.mapbox.com/mapbox-search-js/guides/)\n  - [Search JS React](https://docs.mapbox.com/mapbox-search-js/api/react/)\n  - [Search JS Web](https://docs.mapbox.com/mapbox-search-js/api/web/)\n  - [Search JS Core](https://docs.mapbox.com/mapbox-search-js/api/core/)\n- [Search SDK for iOS](https://docs.mapbox.com/ios/search/guides/)\n- [Search SDK for Android](https://docs.mapbox.com/android/search/guides/)\n- [Location Helper Tool](https://labs.mapbox.com/location-helper/) - Calculate bounding boxes\n\n## Quick Decision Guide\n\n**User says: \"I need location search\"**\n\n1. **Ask discovery questions** (Questions 1-6 above)\n2. **Recommend product:**\n   - **Search Box API** (default for all interactive/user-facing search, including address geocoding)\n   - Geocoding API only for batch/server-side/permanent geocoding\n   - Platform SDK preferred (Search JS for web, native SDKs for mobile)\n3. **Implement with:**\n   - ✅ Debouncing\n   - ✅ Session tokens\n   - ✅ Geographic filtering\n   - ✅ Error handling\n   - ✅ Good UX\n4. **Test thoroughly**\n5. **Monitor in production**\n\n**Remember:** The best search implementation asks the right questions first, then builds exactly what the user needs - no more, no less.\n","contentSource":"skills.sh/api/download/mapbox/mapbox-agent-skills/mapbox-search-integration","contentFetchedAt":"2026-07-27T08:59:31.204Z"},{"name":"mapbox-geospatial-operations","url":"https://skills.sh/mapbox/mapbox-agent-skills/mapbox-geospatial-operations","install":"npx skills add mapbox/mapbox-agent-skills --skill mapbox-geospatial-operations","sdk":"mapbox","key":"mapbox/mapbox-geospatial-operations","description":"Expert guidance on choosing the right geospatial tool based on problem type, accuracy requirements, and performance needs","hasContent":true,"content":"---\nname: mapbox-geospatial-operations\ndescription: Expert guidance on choosing the right geospatial tool based on problem type, accuracy requirements, and performance needs\n---\n\n# Mapbox Geospatial Operations Skill\n\nExpert guidance for AI assistants on choosing the right geospatial tools from the Mapbox MCP Server. Focuses on selecting tools based on **what the problem requires** - geometric calculations vs routing, straight-line vs road network, and accuracy needs.\n\n## Core Principle: Problem Type Determines Tool Choice\n\nThe Mapbox MCP Server provides two categories of geospatial tools:\n\n1. **Offline Geometric Tools** - Use Turf.js for pure geometric/spatial calculations\n2. **Routing & Navigation APIs** - Use Mapbox APIs when you need real-world routing, traffic, or travel times\n\n**The key question: What does the problem actually require?**\n\n### Decision Framework\n\n| Problem Characteristic                                 | Tool Category     | Why                                      |\n| ------------------------------------------------------ | ----------------- | ---------------------------------------- |\n| **Straight-line distance** (as the crow flies)         | Offline geometric | Accurate for geometric distance          |\n| **Road/path distance** (as the crow drives)            | Routing API       | Only routing APIs know road networks     |\n| **Travel time**                                        | Routing API       | Requires routing with speed/traffic data |\n| **Point containment** (is X inside Y?)                 | Offline geometric | Pure geometric operation                 |\n| **Geographic shapes** (buffers, centroids, areas)      | Offline geometric | Mathematical/geometric operations        |\n| **Traffic-aware routing**                              | Routing API       | Requires real-time traffic data          |\n| **Route optimization** (best order to visit)           | Routing API       | Complex routing algorithm                |\n| **High-frequency checks** (e.g., real-time geofencing) | Offline geometric | Instant response, no latency             |\n\n## Decision Matrices by Use Case\n\n### Distance Calculations\n\n**User asks: \"How far is X from Y?\"**\n\n| What They Actually Mean                            | Tool Choice                         | Why                                      |\n| -------------------------------------------------- | ----------------------------------- | ---------------------------------------- |\n| Straight-line distance (as the crow flies)         | `distance_tool`                     | Accurate for geometric distance, instant |\n| Driving distance (as the crow drives)              | `directions_tool`                   | Only routing knows actual road distance  |\n| Walking/cycling distance (as the crow walks/bikes) | `directions_tool`                   | Need specific path network               |\n| Travel time                                        | `directions_tool` or `matrix_tool`  | Requires routing with speed data         |\n| Distance with current traffic                      | `directions_tool` (driving-traffic) | Need real-time traffic consideration     |\n\n**Example: \"What's the distance between these 5 warehouses?\"**\n\n- As the crow flies → `distance_tool` (10 calculations, instant)\n- As the crow drives → `matrix_tool` (5×5 matrix, one API call, returns actual route distances)\n\n**Key insight:** Use the tool that matches what \"distance\" means in context. Always clarify: crow flies or crow drives?\n\n### Proximity and Containment\n\n**User asks: \"Which points are near/inside this area?\"**\n\n| Query Type                   | Tool Choice                                           | Why                                                           |\n| ---------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- |\n| \"Within X meters radius\"     | `distance_tool` + filter                              | Simple geometric radius                                       |\n| \"Within X minutes drive\"     | `isochrone_tool` → `point_in_polygon_tool`            | Need routing for travel-time zone, then geometric containment |\n| \"Inside this polygon\"        | `point_in_polygon_tool`                               | Pure geometric containment test                               |\n| \"Reachable by car in 30 min\" | `isochrone_tool`                                      | Requires routing + traffic                                    |\n| \"Nearest to this point\"      | `distance_tool` (geometric) or `matrix_tool` (routed) | Depends on definition of \"nearest\"                            |\n\n**Example: \"Are these 200 addresses in our 30-minute delivery zone?\"**\n\n1. Create zone → `isochrone_tool` (routing API - need travel time)\n2. Check addresses → `point_in_polygon_tool` (geometric - 200 instant checks)\n\n**Key insight:** Routing for creating travel-time zones, geometric for containment checks\n\n### Routing and Navigation\n\n**User asks: \"What's the best route?\"**\n\n| Scenario                            | Tool Choice                         | Why                               |\n| ----------------------------------- | ----------------------------------- | --------------------------------- |\n| A to B directions                   | `directions_tool`                   | Turn-by-turn routing              |\n| Optimal order for multiple stops    | `optimization_tool`                 | Solves traveling salesman problem |\n| Clean GPS trace                     | `map_matching_tool`                 | Snaps to road network             |\n| Just need bearing/compass direction | `bearing_tool`                      | Simple geometric calculation      |\n| Route with traffic                  | `directions_tool` (driving-traffic) | Real-time traffic awareness       |\n| Fixed-order waypoints               | `directions_tool` with waypoints    | Routing through specific points   |\n\n**Example: \"Navigate from hotel to airport\"**\n\n- Need turn-by-turn → `directions_tool`\n- Just need to know \"it's northeast\" → `bearing_tool`\n\n**Key insight:** Routing tools for actual navigation, geometric tools for directional info\n\n### Area and Shape Operations\n\n**User asks: \"Create a zone around this location\"**\n\n| Requirement               | Tool Choice      | Why                      |\n| ------------------------- | ---------------- | ------------------------ |\n| Simple circular buffer    | `buffer_tool`    | Geometric circle/radius  |\n| Travel-time zone          | `isochrone_tool` | Based on routing network |\n| Calculate area size       | `area_tool`      | Geometric calculation    |\n| Simplify complex boundary | `simplify_tool`  | Geometric simplification |\n| Find center of shape      | `centroid_tool`  | Geometric centroid       |\n\n**Example: \"Show 5km coverage around each store\"**\n\n- 5km radius → `buffer_tool` (geometric circles)\n- \"What customers can reach in 15 min?\" → `isochrone_tool` (routing-based)\n\n**Key insight:** Geometric tools for distance-based zones, routing tools for time-based zones\n\n## Performance and Scale Considerations\n\n### When Volume Affects Tool Choice\n\n**Small operations (< 100 calculations):**\n\n- Geometric tools: Instant, iterate freely\n- Routing APIs: Fast enough for most uses\n\n**Medium operations (100-1,000 calculations):**\n\n- Geometric tools: Still fast, no concerns\n- Routing APIs: Consider batch operations (matrix_tool)\n\n**Large operations (> 1,000 calculations):**\n\n- Geometric tools: May need optimization but still fast\n- Routing APIs: Definitely use batch tools (matrix_tool handles up to 25×25)\n\n**Key insight:** Volume rarely affects geometric tool choice, but routing APIs have batch tools for efficiency\n\n### Real-Time vs Batch\n\n| Use Case                            | Approach             | Tool Choice                              |\n| ----------------------------------- | -------------------- | ---------------------------------------- |\n| Real-time geofencing (every second) | Geometric checks     | `point_in_polygon_tool` (instant)        |\n| Route planning (one-time)           | Full routing         | `directions_tool` or `optimization_tool` |\n| Periodic proximity checks           | Geometric distance   | `distance_tool`                          |\n| Live traffic routing                | Routing with traffic | `directions_tool` (driving-traffic)      |\n\n**Architecture note for high-frequency geofencing:** If the application calls containment checks at very high rates (e.g., 50 vehicles every 2 seconds = 25 checks/second), calling MCP tools over the network adds agent-reasoning overhead that makes it impractical. In those cases, recommend using Turf.js directly in-process (`turf.booleanPointInPolygon`) for the hot path, and reserve MCP tools for peripheral tasks like zone definition (`isochrone_tool`), rerouting (`directions_tool`), or visualization (`static_map_image_tool`).\n\n## Common Scenarios and Optimal Approaches\n\n### Scenario 1: Store Locator\n\n**User: \"Find the closest store and show 5km coverage\"**\n\n**Optimal approach:**\n\n1. Search stores → `category_search_tool` (returns distances automatically)\n2. Create coverage zone → `buffer_tool` (5km geometric circle)\n3. Visualize → `static_map_image_tool`\n\n**Why:** Search already gives distances; geometric buffer for simple radius\n\n### Scenario 2: Delivery Route Optimization\n\n**User: \"Optimize delivery to 8 addresses / stops\"**\n\n**Optimal approach:**\n\n1. **Geocode addresses (if needed)** → Use `search_and_geocode_tool` to convert any street addresses to coordinates. Even when coordinates are already provided, mention this as an optional pre-step — real-world delivery lists often contain a mix of addresses and coordinates.\n2. **Optimize route** → `optimization_tool` (TSP solver — reorders stops to minimize total drive time)\n\n**Why `optimization_tool` and NOT these alternatives:**\n\n- **`directions_tool`** only routes A → B (or through fixed-order waypoints). It does NOT reorder stops — if you pass 8 stops, it routes them in the order given, which is almost never optimal.\n- **`matrix_tool`** gives travel times between all pairs of stops (8×8 = 64 values), but it does NOT compute the optimal ordering. You'd need to solve TSP yourself on top of the matrix — `optimization_tool` does this for you in one call.\n\nAlways mention `search_and_geocode_tool` as a useful companion for geocoding delivery addresses before optimization.\n\n### Scenario 3: Service Area Validation\n\n**User: \"Which of these 200 addresses can we deliver to in 30 minutes?\"**\n\n**Optimal approach:**\n\n1. Create delivery zone → `isochrone_tool` (30-minute driving)\n2. Check each address → `point_in_polygon_tool` (200 geometric checks)\n\n**Why:** Routing for accurate travel-time zone, geometric for fast containment checks\n\n### Scenario 4: GPS Trace Analysis\n\n**User: \"How long was this bike ride?\"**\n\n**Optimal approach:**\n\n1. Clean GPS trace → `map_matching_tool` (snap to bike paths)\n2. Get distance → Use API response or calculate with `distance_tool`\n\n**Why:** Need road/path matching; distance calculation either way works\n\n### Scenario 5: Coverage Analysis\n\n**User: \"What's our total service area?\"**\n\n**Optimal approach:**\n\n1. Create buffers around each location → `buffer_tool`\n2. Calculate total area → `area_tool`\n3. Or, if time-based → `isochrone_tool` for each location\n\n**Why:** Geometric for distance-based coverage, routing for time-based\n\n## Anti-Patterns: Using the Wrong Tool Type\n\n### ❌ Don't: Use geometric tools for routing questions\n\n```javascript\n// WRONG: User asks \"how long to drive there?\"\ndistance_tool({ from: A, to: B });\n// Returns 10km as the crow flies, but actual drive is 15km\n\n// CORRECT: Need routing for driving distance\ndirections_tool({\n  coordinates: [\n    { longitude: A[0], latitude: A[1] },\n    { longitude: B[0], latitude: B[1] }\n  ],\n  routing_profile: 'mapbox/driving'\n});\n// Returns actual road distance and drive time as the crow drives\n```\n\n**Why wrong:** As the crow flies ≠ as the crow drives\n\n### ❌ Don't: Use routing APIs for geometric operations\n\n```javascript\n// WRONG: Check if point is in polygon\n// (Can't do this with routing APIs)\n\n// CORRECT: Pure geometric operation\npoint_in_polygon_tool({ point: location, polygon: boundary });\n```\n\n**Why wrong:** Routing APIs don't do geometric containment\n\n### ❌ Don't: Confuse \"near\" with \"reachable\"\n\n```javascript\n// User asks: \"What's reachable in 20 minutes?\"\n\n// WRONG: 20-minute distance at average speed\ndistance_tool + calculate 20min * avg_speed\n\n// CORRECT: Actual routing with road network\nisochrone_tool({\n  coordinates: {longitude: startLng, latitude: startLat},\n  contours_minutes: [20],\n  profile: \"mapbox/driving\"\n})\n```\n\n**Why wrong:** Roads aren't straight lines; traffic varies\n\n### ❌ Don't: Use routing when bearing is sufficient\n\n```javascript\n// User asks: \"Which direction is the airport?\"\n\n// OVERCOMPLICATED: Full routing\ndirections_tool({\n  coordinates: [\n    { longitude: hotel[0], latitude: hotel[1] },\n    { longitude: airport[0], latitude: airport[1] }\n  ]\n});\n\n// BETTER: Just need bearing\nbearing_tool({ from: hotel, to: airport });\n// Returns: \"Northeast (45°)\"\n```\n\n**Why better:** Simpler, instant, answers the actual question\n\n## Hybrid Approaches: Combining Tool Types\n\nSome problems benefit from using both geometric and routing tools:\n\n### Pattern 1: Routing + Geometric Filter\n\n```\n1. directions_tool → Get route geometry\n2. buffer_tool → Create corridor around route\n3. category_search_tool → Find POIs in corridor\n4. point_in_polygon_tool → Filter to those actually along route\n```\n\n**Use case:** \"Find gas stations along my route\"\n\n### Pattern 2: Routing + Distance Calculation\n\n```\n1. category_search_tool → Find 10 nearby locations\n2. distance_tool → Calculate straight-line distances (geometric)\n3. For top 3, use directions_tool → Get actual driving time\n```\n\n**Use case:** Quickly narrow down, then get precise routing for finalists\n\n### Pattern 3: Isochrone + Containment\n\n```\n1. isochrone_tool → Create travel-time zone (routing)\n2. point_in_polygon_tool → Check hundreds of addresses (geometric)\n```\n\n**Use case:** \"Which customers are in our delivery zone?\"\n\n## Decision Algorithm\n\nWhen user asks a geospatial question:\n\n```\n1. Does it require routing, roads, or travel times?\n   YES → Use routing API (directions, matrix, isochrone, optimization)\n   NO → Continue\n\n2. Does it require traffic awareness?\n   YES → Use directions_tool or isochrone_tool with traffic profile\n   NO → Continue\n\n3. Is it a geometric/spatial operation?\n   - Distance between points (straight-line) → distance_tool\n   - Point containment → point_in_polygon_tool\n   - Area calculation → area_tool\n   - Buffer/zone → buffer_tool\n   - Direction/bearing → bearing_tool\n   - Geometric center → centroid_tool\n   - Bounding box → bounding_box_tool\n   - Simplification → simplify_tool\n\n4. Is it a search/discovery operation?\n   YES → Use search tools (search_and_geocode, category_search)\n```\n\n## Key Decision Questions\n\nBefore choosing a tool, ask:\n\n1. **Does \"distance\" mean as the crow flies or as the crow drives?**\n   - As the crow flies (straight-line) → geometric tools\n   - As the crow drives (road distance) → routing APIs\n\n2. **Does the user need travel time?**\n   - Yes → routing APIs (only they know speeds/traffic)\n   - No → geometric tools may suffice\n\n3. **Is this about roads/paths or pure spatial relationships?**\n   - Roads/paths → routing APIs\n   - Spatial relationships → geometric tools\n\n4. **Does this need to happen in real-time with low latency?**\n   - Yes + geometric problem → offline tools (instant)\n   - Yes + routing problem → use routing APIs (still fast)\n\n5. **Is accuracy critical, or is approximation OK?**\n   - Critical + routing → routing APIs\n   - Approximation OK → geometric tools may work\n\n## Terminology Guide\n\nUnderstanding what users mean:\n\n| User Says             | Usually Means                                      | Tool Type   |\n| --------------------- | -------------------------------------------------- | ----------- |\n| \"Distance\"            | Context-dependent! Ask: crow flies or crow drives? | Varies      |\n| \"How far\"             | Often as the crow drives (road distance)           | Routing API |\n| \"Nearby\"              | Usually as the crow flies (straight-line radius)   | Geometric   |\n| \"Close\"               | Could be either - clarify!                         | Ask         |\n| \"Reachable\"           | Travel-time based (crow drives with traffic)       | Routing API |\n| \"Inside/contains\"     | Geometric containment                              | Geometric   |\n| \"Navigate/directions\" | Turn-by-turn routing                               | Routing API |\n| \"Bearing/direction\"   | Compass direction (crow flies)                     | Geometric   |\n\n## Quick Reference\n\n### Geometric Operations (Offline Tools)\n\n- `distance_tool` - Straight-line distance between two points\n- `bearing_tool` - Compass direction from A to B\n- `midpoint_tool` - Midpoint between two points\n- `point_in_polygon_tool` - Is point inside polygon?\n- `area_tool` - Calculate polygon area\n- `buffer_tool` - Create circular buffer/zone\n- `centroid_tool` - Geometric center of polygon\n- `bbox_tool` - Min/max coordinates of geometry\n- `simplify_tool` - Reduce geometry complexity\n\n### Routing & Navigation (APIs)\n\n- `directions_tool` - Turn-by-turn routing\n- `matrix_tool` - Many-to-many travel times\n- `optimization_tool` - Route optimization (TSP)\n- `isochrone_tool` - Travel-time zones\n- `map_matching_tool` - Snap GPS to roads\n\n### When to Use Each Category\n\n**Use Geometric Tools When:**\n\n- Problem is spatial/mathematical (containment, area, bearing)\n- Straight-line distance is appropriate\n- Need instant results for real-time checks\n- Pure geometry (no roads/traffic involved)\n\n**Use Routing APIs When:**\n\n- Need actual driving/walking/cycling distances\n- Need travel times\n- Need to consider road networks\n- Need traffic awareness\n- Need route optimization\n- Need turn-by-turn directions\n\n## Integration with Other Skills\n\n**Works with:**\n\n- **mapbox-search-patterns**: Search for locations, then use geospatial operations\n- **mapbox-web-performance-patterns**: Optimize rendering of geometric calculations\n- **mapbox-token-security**: Ensure requests use properly scoped tokens\n\n## Resources\n\n- [Mapbox MCP Server](https://github.com/mapbox/mcp-server)\n- [Turf.js Documentation](https://turfjs.org/) (Powers geometric tools)\n- [Mapbox Directions API](https://docs.mapbox.com/api/navigation/directions/)\n- [Mapbox Isochrone API](https://docs.mapbox.com/api/navigation/isochrone/)\n- [Mapbox Matrix API](https://docs.mapbox.com/api/navigation/matrix/)\n- [Mapbox Optimization API](https://docs.mapbox.com/api/navigation/optimization/)\n","contentSource":"skills.sh/api/download/mapbox/mapbox-agent-skills/mapbox-geospatial-operations","contentFetchedAt":"2026-07-27T08:59:31.356Z"}],"official":true,"generatedAt":"2026-07-27T09:02:29.956Z"}