Emergency Hotline: Call 1-844-363-1423 (United We Dream Hotline)
ICE Encounter

Choosing the Right Framework

The foundation of any advocacy mapping platform rests on selecting the appropriate JavaScript rendering library. Three frameworks dominate the open-source landscape:

  • Leaflet - Lightweight, DOM-based
  • MapLibre GL JS - WebGL hardware-accelerated
  • OpenLayers - Enterprise-grade, feature-rich

Each has distinct architectural paradigms affecting performance, scalability, and suitability for specific use cases.


Leaflet

Architecture

Leaflet operates as a lightweight, DOM-based two-dimensional rendering engine using HTML elements and SVG for vector drawing.

Key Characteristics

Aspect Details
Bundle Size ~40KB minified/gzipped
Rendering DOM manipulation (HTML/SVG)
License BSD-2-Clause
Plugin Ecosystem Extensive third-party plugins

Advantages

  • Ultra-lightweight - Minimal payload ideal for low-bandwidth areas
  • Fast initialization - No heavy graphics processing needed
  • Simple API - Gentle learning curve
  • Native DOM - Excellent screen reader accessibility
  • Permissive license - No unexpected fees

Limitations

  • Performance degrades past ~5,000 features
  • DOM manipulation becomes slow with dense data
  • Raster-focused - Limited vector tile support

Best Use Cases

  • Simple checkpoint maps
  • Mobile users in rural/border areas with poor connectivity
  • Quick deployment with minimal configuration
  • Accessibility-critical applications

MapLibre GL JS

Architecture

MapLibre uses WebGL for hardware-accelerated rendering, processing vector tiles natively in the browser.

History

MapLibre emerged as a community-driven fork of Mapbox GL JS after Mapbox transitioned to a proprietary license. It maintains full compatibility while remaining truly open-source.

Key Characteristics

Aspect Details
Bundle Size Moderate to heavy
Rendering WebGL hardware-accelerated
License BSD-3-Clause
Data Format Vector tiles (.pbf)

Advantages

  • Scales efficiently - Handles millions of features
  • Dynamic styling - Client-side filtering without new server requests
  • Smooth interactions - 60fps pan/zoom on capable hardware
  • Vector tiles - Smaller files, dynamic styling

Limitations

  • Slower initial load - Heavier JavaScript bundle
  • Hardware requirements - Requires WebGL-capable browser
  • Accessibility challenges - Canvas renders as opaque to screen readers
  • Higher variance - ~17ms standard deviation vs 4.8ms for OpenLayers

Best Use Cases

  • Nationwide analytical dashboards
  • Large datasets (detention facilities, historical records)
  • Dynamic filtering (toggle facility types, time ranges)
  • Interactive data visualization

OpenLayers

Architecture

OpenLayers is the most feature-rich option, designed for enterprise-grade GIS operations.

Key Characteristics

Aspect Details
Bundle Size Heavy
Rendering Canvas and WebGL
License BSD-2-Clause
GIS Features Complex projections, CAD editing, advanced formats

Advantages

  • Consistent performance - 4.8ms standard deviation
  • Extreme scale - 100,000+ lines render twice as fast as competitors
  • Full GIS support - Projections, coordinate systems, editing tools
  • Format support - Extensive geospatial format compatibility

Limitations

  • Steep learning curve - Complex API architecture
  • Large bundle - Over-engineered for simple use cases
  • Development time - More configuration required

Best Use Cases

  • Internal analyst-facing tools
  • Complex projection transformations
  • Spatial data editing
  • Enterprise GIS integration

Performance Benchmarks

Rendering Speed (100,000 lines)

Library Speed Standard Deviation
OpenLayers Fastest 4.8ms
Leaflet Moderate 6.6ms
MapLibre Slower 17ms

Feature Scaling

Feature Count Leaflet MapLibre OpenLayers
1,000 ✅ Smooth ✅ Smooth ✅ Smooth
5,000 ⚠️ Degrading ✅ Smooth ✅ Smooth
10,000 ❌ Sluggish ✅ Smooth ✅ Smooth
100,000 ❌ Unusable ✅ Smooth ✅ Excellent

Accessibility Comparison

Feature Leaflet MapLibre OpenLayers
Screen readers ✅ Native DOM elements ⚠️ Requires ARIA injection ⚠️ Moderate
Keyboard navigation ✅ Tab through markers ⚠️ Requires custom handlers ⚠️ Moderate
Focus management ✅ Native ❌ Manual implementation ⚠️ Partial

Leaflet Accessibility

// Markers are native DOM elements with alt text
L.marker([lat, lng], {
  alt: 'Permanent Border Patrol Checkpoint'
}).addTo(map);

MapLibre Accessibility

// Canvas requires explicit ARIA labeling
map.getCanvas().setAttribute('aria-label',
  'Interactive map showing immigration checkpoints');

Bundle Size Impact

Library Minified + Gzipped Relative Size
Leaflet ~40KB 1x (baseline)
MapLibre GL JS ~380KB ~9.5x
OpenLayers ~220KB ~5.5x

For mobile users on cellular:

  • 40KB loads in ~1 second on 3G
  • 380KB loads in ~10 seconds on 3G

Decision Framework

Use Leaflet When:

  • [ ] Target audience is mobile-first
  • [ ] Network conditions are unreliable (border regions)
  • [ ] Feature count is under 5,000
  • [ ] Accessibility is critical
  • [ ] Quick deployment is needed
  • [ ] Simple checkpoint/facility markers

Use MapLibre When:

  • [ ] Displaying massive datasets (100,000+ features)
  • [ ] Dynamic client-side filtering required
  • [ ] Vector tile infrastructure available
  • [ ] Users have modern hardware
  • [ ] Smooth animations are important
  • [ ] Complex data visualization

Use OpenLayers When:

  • [ ] Internal analyst tools
  • [ ] Complex coordinate projections
  • [ ] Spatial data editing workflows
  • [ ] Enterprise GIS integration
  • [ ] Maximum rendering consistency
  • [ ] Advanced format requirements

Integration with 11ty

Leaflet Setup

<!-- In your 11ty template -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script defer src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

MapLibre Setup

<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.css" />
<script defer src="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js"></script>

Lazy Loading (Recommended)

// Load map only when scrolled into view
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      initializeMap();
      observer.disconnect();
    }
  });
});

observer.observe(document.getElementById('map-container'));

Hybrid Approaches

For complex applications, consider hybrid architectures:

Scenario Solution
Simple overview + detailed drill-down Leaflet for overview, MapLibre for detail
Mobile + desktop Detect device, load appropriate library
Accessibility + performance Leaflet with accessible overlays, MapLibre for visual layers

Related Guides