
Mapbox Style Patterns
Copy vetted Mapbox GL layer and data-driven styling patterns when building or tuning interactive maps in the frontend.
Overview
mapbox-style-patterns is an agent skill for the Build phase that supplies common Mapbox GL layer configurations and data-driven styling expression patterns for interactive maps.
Install
npx skills add https://github.com/mapbox/mapbox-agent-skills --skill mapbox-style-patternsWhat is this skill?
- Layer types quick reference table for fill, line, symbol, circle, heatmap, fill-extrusion, and raster
- Data-driven fill-color via match on property type with sensible defaults
- circle-radius interpolate linear on population for proportional point sizing
- Zoom-step visibility patterns to show labels or layers only at appropriate zoom levels
- Ready-to-paste Mapbox GL JavaScript expression snippets
- 7 layer types in quick reference table (fill, line, symbol, circle, heatmap, fill-extrusion, raster)
Adoption & trust: 1.2k installs on skills.sh; 64 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are adding Mapbox layers but keep looking up expression syntax for match, interpolate, step, and layer-type-specific paint properties.
Who is it for?
Indie SaaS or internal tools with Mapbox GL JS or compatible runtimes that need fast, correct styling snippets during UI map work.
Skip if: Projects using only static map images, non-Mapbox engines, or teams that already maintain a complete internal style guide with no agent assistance.
When should I use this skill?
User or agent is configuring Mapbox styles, layers, or data-driven paint and needs vetted pattern examples.
What do I get? / Deliverables
You paste validated layer recipes into your style or runtime code so maps render categories, sizes, and zoom behavior correctly on the first iteration.
- Layer configuration snippets
- Data-driven expression blocks for copy into style code
Recommended Skills
Journey fit
Map style configuration is implemented in the product UI layer during active feature work, before ship-time performance tuning. Frontend subphase fits because patterns cover fill, line, symbol, circle, heatmap, fill-extrusion, and raster layers with expression-based properties.
How it compares
Reference snippet pack for Mapbox expressions—not an MCP server or a full style authoring pipeline.
Common Questions / FAQ
Who is mapbox-style-patterns for?
Frontend-focused solo builders and agents embedding Mapbox maps who want authoritative layer and expression examples without reading the entire style spec each time.
When should I use mapbox-style-patterns?
During Build frontend work while defining layers for polygons, roads, labels, heatmaps, or 3D buildings, or when tuning zoom-dependent visibility and data-driven colors.
Is mapbox-style-patterns safe to install?
Check the Security Audits panel on this Prism page; the skill is documentation-only patterns with no prescribed shell or network operations in the provided README.
SKILL.md
READMESKILL.md - Mapbox Style Patterns
# Mapbox Style Patterns Quick reference for common style patterns, layer configurations, and data-driven styling. ## Layer Types Quick Reference | Layer Type | Use For | Key Properties | | ------------------ | --------------------------- | ------------------------------------ | | **fill** | Polygons (countries, parks) | `fill-color`, `fill-opacity` | | **line** | Roads, boundaries | `line-color`, `line-width` | | **symbol** | Labels, icons | `text-field`, `icon-image` | | **circle** | Points (markers, heatmap) | `circle-radius`, `circle-color` | | **heatmap** | Density visualization | `heatmap-intensity`, `heatmap-color` | | **fill-extrusion** | 3D buildings | `fill-extrusion-height` | | **raster** | Satellite, aerial imagery | `raster-opacity` | ## Data-Driven Styling Patterns ### Based on Property Value ```javascript // ✅ Color by category 'fill-color': [ 'match', ['get', 'type'], 'park', '#90EE90', 'water', '#87CEEB', 'urban', '#D3D3D3', '#CCCCCC' // default ] // ✅ Size by numeric value 'circle-radius': [ 'interpolate', ['linear'], ['get', 'population'], 0, 5, 1000000, 20 ] ``` ### Based on Zoom Level ```javascript // ✅ Show/hide by zoom 'visibility': [ 'step', ['zoom'], 'none', // Hidden below zoom 10 10, 'visible' ] // ✅ Size by zoom 'text-size': [ 'interpolate', ['linear'], ['zoom'], 8, 10, // Small at zoom 8 16, 18 // Large at zoom 16 ] ``` ## Common Patterns ### 1. Clustering ```javascript map.addSource('points', { type: 'geojson', data: geojson, cluster: true, clusterRadius: 50, clusterMaxZoom: 14 }); // Cluster circles map.addLayer({ id: 'clusters', type: 'circle', source: 'points', filter: ['has', 'point_count'], paint: { 'circle-color': ['step', ['get', 'point_count'], '#51bbd6', 100, '#f1f075', 750, '#f28cb1'], 'circle-radius': ['step', ['get', 'point_count'], 20, 100, 30, 750, 40] } }); ``` ### 2. Feature State (Hover/Selection) ```javascript // ✅ Hover effect without modifying data map.on('mousemove', 'layer', (e) => { if (hoveredId) { map.setFeatureState( { source: 'source', id: hoveredId }, { hover: false } ); } hoveredId = e.features[0].id; map.setFeatureState( { source: 'source', id: hoveredId }, { hover: true } ); }); // Style based on state 'fill-color': [ 'case', ['boolean', ['feature-state', 'hover'], false], '#0080ff', // Hover color '#3bb2d0' // Default color ] ``` ### 3. Filters ```javascript // ✅ Filter by property map.setFilter('layer', ['==', ['get', 'type'], 'restaurant']); // ✅ Filter by multiple conditions map.setFilter('layer', ['all', ['==', ['get', 'type'], 'restaurant'], ['>', ['get', 'rating'], 4]]); // ✅ Filter by zoom map.setFilter('layer', ['all', ['>=', ['zoom'], 10], ['<', ['zoom'], 14]]); ``` ### 4. Expressions ```javascript // ✅ Conditional styling 'circle-color': [ 'case', ['<', ['get', 'value'], 10], '#00ff00', // Green if < 10 ['<', ['get', 'value'], 20], '#ffff00', // Yellow if < 20 '#ff0000' // Red otherwise ] // ✅ Math operations 'circle-radius': [ '*', ['sqrt', ['get', 'population']], 0.01 ] // ✅ String concatenation 'text-field': ['concat', 'Population: ', ['get', 'pop']] ``` ## Performance Patterns ### Vector Tiles vs GeoJSON **Use vector tiles when:** - Large datasets (>5MB) - Need different zoom levels - Want server-side updates **Use GeoJSON when:** - Small datasets (<5MB) - Frequent client-side updates - Simple implementation needed ### Layer Optimization ```javascript // ✅ Set minzoom/maxzoom map.addLayer({ id: 'layer', minzoom: 10, // Only show zoom 10+ maxzoom: 16 // Hide above zoom 16 }); // ✅ Use feature state instead of removing/re-adding // Bad: map.removeLayer() / map.addLaye