Implementation of Custom Map Styles in a Mobile Application
A gray Google map with green parks — a recognizable default that immediately says "we didn't bother with design." Custom style integrates the map into the app's visual language, removes unnecessary POI, and highlights what matters to your user.
Tools for Creating Style
Google Maps: Google Maps Platform Styling Wizard generates JSON style config. More powerful variant — Snazzy Maps with ready-made style library. JSON describes each map layer: roads, buildings, water, labels, POI — with color, visibility, and weight settings.
Mapbox: Studio with visual editor and style export as URL mapbox://styles/.... Mapbox is more flexible for customization: you can add own layers with data on top of base map.
Apple Maps (MapKit): starting iOS 16 there's MKMapConfiguration with choice between .standard, .hybrid, and .imagery. No custom JSON style — only choice of scheme (light/dark via colorScheme) and shown POI via pointOfInterestFilter.
Applying JSON Style on iOS
let style = """
[{
"featureType": "poi",
"stylers": [{"visibility": "off"}]
},{
"featureType": "transit",
"stylers": [{"visibility": "off"}]
},{
"featureType": "road",
"elementType": "geometry",
"stylers": [{"color": "#1a1a2e"}]
}]
"""
if let mapStyle = try? GMSMapStyle(jsonString: style) {
mapView.mapStyle = mapStyle
}
Style JSON is better stored as .json file in Bundle, not string in code: GMSMapStyle(contentsOfFileURL: Bundle.main.url(forResource: "map_style", withExtension: "json")!). On parse error, GMSMapStyle throws exception — always wrap in try? and provide fallback to standard style.
Android
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(context, R.raw.map_style)
)
if (!success) {
Log.e("MapStyle", "Style parsing failed")
}
R.raw.map_style — file map_style.json in res/raw/. On parse failure, method returns false without exception — don't forget to check.
Dark Theme
To support dark theme, don't create two different styles — use parameters in JSON with variables, or switch between two pre-loaded GMSMapStyle / MapStyleOptions objects on UIUserInterfaceStyle / Configuration.uiMode change.
On iOS, subscribe to traitCollectionDidChange(_:) and switch style. On Android — AppCompatDelegate.getDefaultNightMode() on map initialization.
Mapbox as Alternative
If you need fully custom layers — own data on top of base map, animated route lines, 3D buildings with custom textures — Mapbox GL Native (iOS/Android) or mapbox_maps_flutter. Style described via Mapbox Style Specification, hosted in Mapbox Studio or self-hosted on own CDN.
Cost difference: Google Maps free up to 28,000 map loads per month, Mapbox — up to 50,000. At higher volumes, Mapbox is more economical.
Timeline: one to two days — create style, integrate into app, support light/dark theme.







