Skip to content

Engineering

Mapbox GL JS in Velocity X — Vector Tiles, Custom Styles, and Why It Beats Google Maps for Custom CRM UIs

Vector Tiles, Brand Control, and Why Google Maps JS Is Fine But Mapbox Is Better

🗺️ 🎨

Velocity X's field-map UI uses Mapbox GL JS, not Google Maps. That choice cascades through the whole architecture: vector tiles instead of raster, custom style URLs, GeoJSON sources, heatmap layers, territory polygons, and a free tier that doesn't make you cry at the end of the month. This piece explains why.

Google Maps JS Is Fine. Mapbox GL JS Is Better for Custom UIs.

Google Maps JavaScript API is the safe default. It's stable, well-documented, and integrates seamlessly with Google Cloud. If you're building a service locator or a delivery tracker, it's the right choice.

But if you're building a field-sales CRM with territories, heatmaps, and custom branding, Mapbox GL JS wins on three fronts: full style control (brand your map colours, not Google's greys), vector tiles (fast rendering, smaller payloads, custom data layers), and pricing that doesn't punish scale.

Velocity X needs to render 10k–50k pins per territory, overlay heatmaps, draw territory polygons, and let teams lasso-select prospects in a single region. Google Maps JS can do it, but Mapbox GL JS does it faster, cheaper, and with visual cohesion your brand actually owns.

Architecture: mapbox-gl, Custom Style URL, GeoJSON Sources, Layers

Velocity X's map stack is four layers: the base Mapbox GL instance, a custom style URL (brand colours), GeoJSON sources (pins, polygons, heatmap data), and layer definitions that stack those sources on top of the base.

The base map. `mapbox-gl` npm package, initialised with your access token and pointing to a style URL. Style URLs are Mapbox URLs that bundle basemap design + vector tile sources. Velocity X uses Mapbox's "Streets" style as a starting point, customised with brand colours for labels, roads, and water.

Custom style URL. Mapbox Studio lets you edit styles visually — change the blue of water, the grey of roads, the font of labels — and publish a style URL. Velocity X's style is a single URL that every client loads, so a design tweak (e.g. "make water darker") applies across every deployed instance without code changes.

GeoJSON sources. Data layers are GeoJSON. A source for pins (type: geojson, data: geojson feature collection). A source for territory polygons. A source for heatmap intensity (points, each with a "density" property). Sources are immutable — if data changes (a new lead is added), you rebuild the GeoJSON and call `map.getSource('pins').setData(newGeoJSON)`.

Layers. Each source gets one or more layers. The pins source might have three layers: a circle for the pin, a symbol for the label, and an invisible click-target layer for interactions. The heatmap source gets a `heatmap` layer (built-in Mapbox layer type) that colours intensity red-to-blue. Territory polygons get a `fill` layer (semi-transparent, brand colour) and a `line` layer (1px, darker shade) for the boundary.

The magic: layers stack by z-index (order of insertion). Heatmap first, then territory fills, then pins, then labels. A click on a pin fires a `map.on('click', 'pins-layer')` event. Lasso selection uses Mapbox GL Draw (an open-source plugin) to capture a polygon, then queries "which GeoJSON points fall inside this polygon?" via `turf.js` (a spatial library).

Why Vector Tiles Beat Raster

Google Maps ships raster tiles — pre-rendered PNG images. Every pan/zoom loads new images. Smaller file size per tile, but you can't query or restyle them without rebuilding them server-side.

Mapbox GL ships vector tiles — raw geographic data (geometries + properties) compressed into tiles. The browser renders them on-the-fly. Panning and zooming is smooth because you're not loading new images, just repositioning vectors. Styling is client-side CSS-like; you can change the basemap colour in-browser without reloading. Adding a custom data layer (heatmap, territory polygon) is one GeoJSON source + one layer definition.

For Velocity X, the payoff: a 50-rep territory map with 10k leads loads in ~200ms (vector tile network + GeoJSON parse). The same map in Google Maps JS would be bottlenecked by raster tile size and would require server-side image compositing for custom overlays. Vector wins.

Cost Comparison: Mapbox vs Google Maps

Google Maps. $200/month free credit. Beyond that, $7 per 1k map loads + $1 per 1k additional data layer requests. Heatmaps count as data layers. A team with 50 reps, each checking the map 10 times per day = 500 loads/day × 30 days = 15k loads/month. That's $105 beyond the credit. Add heatmap + territory queries, you're at $150–$200/month per deployment.

Mapbox GL JS. Free tier: 50k map loads + 25k vector tile requests per month. No data layers, no heatmap surcharge. Paid tier: $100/month for unlimited loads + 10x vector tile requests. Velocity X's demo deployment (5 team demos, 10 maps/day each) runs entirely on the free tier. A customer with 50 reps fits under free tier for months 1–3, then moves to the $100/month paid tier. Huge win for early-stage customers.

Frequently Asked Questions

Can I style the map to match my brand?

Yes. Mapbox Studio editor is visual — no code. Change water colour, road colour, label font, label colour. Publish the style, get a style URL, drop it into Velocity X's initialisation. One URL per brand.

What if Mapbox goes down?

Your map won't render. However, Mapbox's SLA is 99.95% uptime (better than Google Maps's 99.9%). If geography is critical, you'd pair Mapbox with offline-capable vector tiles (e.g. MBTiles), but Velocity X assumes internet connectivity for real-time lead sync anyway.

Can I add custom layers (e.g. traffic, weather, air quality)?

Yes, via third-party GeoJSON sources or raster tile URLs. Velocity X's heatmap and territory overlays are custom GeoJSON layers. You can layer in anything that's GeoJSON or XYZ tiles.

How many pins can Mapbox handle on one map?

Practically, 10k–50k pins before render lag becomes noticeable. Velocity X clusters pins at zoom level 8 and below (e.g. "523 leads in this region") so users see aggregate counts before diving into a territory. Clustering is a Mapbox layer property, not code.

Does Mapbox support offline maps?

Not natively in the browser. The Mapbox Maps SDK for Android/iOS supports offline vector tiles via MBTiles. Velocity X is web-first, so offline isn't in scope, but it's possible if a team needs field access without connectivity.

How do I migrate from Google Maps JS to Mapbox GL JS?

Roughly: remap your sources (Google KmlLayer → Mapbox GeoJSON source), replace layer rendering code (Google infoWindow → Mapbox popup), update the map initialisation. If you're starting from scratch, Mapbox-first is the faster path.

The Bottom Line

Mapbox GL JS is the right choice when you need vector-tile performance, full style control, and a free tier that doesn't penalise growth. Velocity X uses it to render fast, brand your map, and ship cost-effectively to early-stage teams. If you're building a field-sales CRM or territory-driven product, you'll reach for Mapbox. Google Maps is still the right call for service locators and basic deliveries. Know the tradeoff. See how Velocity X structures its territory mapping on top of it. Or start building your own at pricing.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.