Maps
Maps are the most expensive feature nobody budgets for. Tile requests, geocoding calls, and marker rendering add up fast.
Pick the map library before you pick the map provider. The library locks you in harder than the tile source.
Library Selection
| Criteria | MapBox GL JS | Leaflet | Google Maps | react-map-gl |
|---|---|---|---|---|
| Cost | Free to 50K loads/mo | Free (OSS) | $200 credit then pay | Uses MapBox |
| Bundle size | ~200 KB | ~40 KB | External script | ~60 KB + MapBox |
| Vector tiles | Yes | Plugin only | Yes | Yes |
| 3D terrain | Yes | No | Limited | Yes |
| Offline | Yes (paid) | Yes (manual) | No | Via MapBox |
| React wrapper | react-map-gl | react-leaflet | @react-google-maps | Native |
| Best for | Rich interactivity | Lightweight, budget | Enterprise, Places API | React + MapBox |
Decision Rule
| Situation | Choice | Why |
|---|---|---|
| Budget is zero | Leaflet + OpenStreetMap | No API keys, no bills |
| Need geocoding/places | Google Maps | Places API is unmatched |
| Need custom styling | MapBox | Vector tiles, full control |
| Need 3D or terrain | MapBox | Only real option in React |
| Simple location pins | Leaflet | Lightest bundle, fastest render |
Key Patterns
| Pattern | What | Why |
|---|---|---|
| Lazy load map | Import map component dynamically | Maps are heavy; defer until visible |
| Cluster markers | Group nearby points | Performance past 100 markers |
| Viewport culling | Only render visible markers | Memory management |
| Server-side static | Generate static map image on server | Zero JS for non-interactive maps |
Links
Context
- Browser Maps APIs — The browser-level map foundations
- Components — Maps are components with extra weight
- Performance — Maps are the first thing to lazy load
- Onchain Interaction — DePIN and location-based protocols need maps
Questions
When does a static map image replace an interactive map?
- What is the real cost per user of MapBox vs Google Maps at 10K monthly active users?
- How do you test map components without hitting external tile servers?
- When does marker count force a switch from DOM to canvas rendering?