- Remove nested git repository from bugulma/frontend/.git - Add all frontend files to main repository tracking - Convert from separate frontend/backend repos to unified monorepo - Preserve all frontend code and development history as tracked files - Eliminate nested repository complexity for simpler development workflow This creates a proper monorepo structure with frontend and backend coexisting in the same repository for easier development and deployment.
9.6 KiB
Map Library Recommendation
Your Use Case Analysis
Current Requirements:
- ✅ Single city map (Bugulma) - not a global/world map
- ✅ Static GeoJSON boundary (200+ points, loaded once)
- ✅ Custom markers for organizations (~50-200)
- ✅ Custom markers for historical landmarks (~10-50)
- ✅ Connection lines between organizations
- ✅ Zoom/pan functionality
- ✅ React 19 support
- ❌ No need for tile layers (OSM/Mapbox tiles)
- ❌ No need for satellite imagery
- ❌ No need for routing/directions
- ❌ No need for geocoding
- ❌ No need for street-level detail
This is a simple, custom map use case - not a general-purpose mapping application.
Current Library: @vnedyalk0v/react19-simple-maps
Pros:
- ✅ React 19 compatible (main reason you're using it)
- ✅ Lightweight (~50KB)
- ✅ SVG-based (good for customization)
- ✅ Already integrated
- ✅ No API keys required
- ✅ Works with static GeoJSON
Cons:
- ❌ Very new/unknown library (1.2.0, published recently)
- ❌ Limited community support (few users, little documentation)
- ❌ Missing critical features:
- No marker clustering
- No viewport culling
- No performance optimizations
- Scale limitation (max 10000)
- ❌ Maintenance risk (single maintainer, may abandon)
- ❌ Bug in current implementation (markers not using Marker component)
Verdict: RISKY ⚠️
The library works but has significant limitations and maintenance concerns.
Option 1: Keep Current Library (Fix Issues) ⭐ RECOMMENDED FOR NOW
Effort: Low (4-6 hours) Risk: Medium (library may not be maintained long-term)
Why This Makes Sense:
- Already working - You've invested time in integration
- Meets your needs - For a single city map, it's sufficient
- No migration cost - Fix bugs instead of rewriting
- React 19 support - Other libraries may not have it yet
What to Do:
- ✅ Fix critical bugs (location data, Marker component)
- ✅ Add viewport culling (custom implementation)
- ✅ Add marker clustering (use
superclusterlibrary) - ✅ Add performance optimizations (memoization, etc.)
- ✅ Monitor library updates, have migration plan ready
When to Migrate:
- Library stops receiving updates
- You need features it can't provide
- Performance becomes unacceptable
- React 19 support available in better libraries
Recommendation: Keep it for now, but have a migration plan ready.
Option 2: Switch to Leaflet ⭐ BEST LONG-TERM
Effort: Medium (8-12 hours) Risk: Low (mature, well-maintained)
Why Leaflet:
- ✅ Most popular open-source mapping library (50K+ GitHub stars)
- ✅ Mature & stable (10+ years, actively maintained)
- ✅ Excellent documentation and community support
- ✅ React wrapper available (
react-leaflet) - ✅ Plugin ecosystem (clustering, custom markers, etc.)
- ✅ Works with GeoJSON (no tiles needed)
- ✅ Performance optimizations built-in
- ✅ Mobile-friendly touch support
Implementation:
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
// Use GeoJSON layer instead of tiles
<MapContainer center={[54.5384152, 52.7955953]} zoom={12}>
<GeoJSON data={bugulmaGeo} />
{organizations.map(org => (
<Marker position={[org.site.latitude, org.site.longitude]}>
<Popup>{org.Name}</Popup>
</Marker>
))}
</MapContainer>
Considerations:
- ⚠️ Bundle size: ~150KB (larger than current)
- ⚠️ React 19: May need to check compatibility
- ✅ Clustering:
react-leaflet-markerclusterplugin - ✅ Performance: Built-in viewport culling
Recommendation: Best choice if you want reliability and features.
Option 3: Use D3.js Directly (No Map Library)
Effort: High (16-24 hours) Risk: Medium (more code to maintain)
Why D3:
- ✅ Full control - No library limitations
- ✅ Lightweight - Only use what you need
- ✅ Performance - Optimize exactly for your use case
- ✅ No dependencies - No library to maintain
- ✅ React 19 - Works with any React version
Implementation:
import { geoMercator, geoPath } from 'd3-geo';
import { select } from 'd3-selection';
import { zoom, zoomIdentity } from 'd3-zoom';
// Custom implementation with D3 projections
const projection = geoMercator().center([52.7955953, 54.5384152]).scale(10000);
const path = geoPath().projection(projection);
Considerations:
- ⚠️ More code - You build everything
- ⚠️ Learning curve - D3 has steep learning curve
- ⚠️ Maintenance - More code to maintain
- ✅ Flexibility - Complete control
Recommendation: Only if you need maximum control and performance.
Option 4: Mapbox GL JS (Overkill)
Effort: Medium (8-10 hours) Risk: Low (but unnecessary)
Why Not:
- ❌ Requires API key (costs money at scale)
- ❌ Overkill for single city map
- ❌ Heavy (~200KB)
- ❌ Complex for simple use case
- ✅ Excellent performance (WebGL-based)
- ✅ Beautiful visuals
Recommendation: Not recommended - Too complex and expensive for your needs.
Option 5: Google Maps (Overkill)
Effort: Medium (8-10 hours) Risk: Low (but unnecessary)
Why Not:
- ❌ Requires API key (costs money)
- ❌ Overkill for single city map
- ❌ Less customization than Leaflet
- ❌ Vendor lock-in
Recommendation: Not recommended - Too expensive and restrictive.
Comparison Table
| Library | Bundle Size | React 19 | Features | Community | Maintenance | Effort to Switch |
|---|---|---|---|---|---|---|
Current (@vnedyalk0v/react19-simple-maps) |
~50KB | ✅ Yes | ⚠️ Limited | ❌ Small | ⚠️ Unknown | N/A |
Leaflet (react-leaflet) |
~150KB | ⚠️ Check | ✅ Full | ✅ Large | ✅ Active | 8-12h |
| D3.js (custom) | ~80KB | ✅ Yes | ✅ Full | ✅ Large | ✅ Active | 16-24h |
| Mapbox GL | ~200KB | ✅ Yes | ✅ Full | ✅ Large | ✅ Active | 8-10h |
| Google Maps | ~150KB | ✅ Yes | ⚠️ Limited | ✅ Large | ✅ Active | 8-10h |
My Recommendation: Hybrid Approach 🎯
Phase 1: Fix Current Library (Immediate)
Time: 4-6 hours Goal: Make current implementation work reliably
- Fix location data access (use Sites)
- Fix Marker component usage
- Add viewport culling
- Add marker clustering (
supercluster) - Add performance optimizations
Why: Minimal effort, gets you working solution quickly.
Phase 2: Evaluate & Plan Migration (1-2 months)
Time: 2-4 hours Goal: Prepare for potential migration
- Monitor current library updates
- Test Leaflet compatibility with React 19
- Create proof-of-concept with Leaflet
- Document migration path
Why: Be prepared if current library becomes problematic.
Phase 3: Migrate if Needed (If library fails)
Time: 8-12 hours Goal: Switch to Leaflet if current library doesn't work out
Why: Leaflet is the safest long-term choice.
Decision Matrix
Choose Current Library (Fix Issues) if:
- ✅ You want to ship quickly
- ✅ You're okay with limited features
- ✅ You can accept maintenance risk
- ✅ You'll migrate later if needed
Choose Leaflet if:
- ✅ You want long-term reliability
- ✅ You need proven features (clustering, etc.)
- ✅ You want community support
- ✅ You're okay with larger bundle size
Choose D3.js if:
- ✅ You need maximum performance
- ✅ You want full control
- ✅ You have time to build custom solution
- ✅ You're comfortable with D3
Final Recommendation
For your use case (single city, static GeoJSON, custom markers):
-
Short-term (next 1-2 months):
- ✅ Keep current library, fix critical bugs
- ✅ Add performance optimizations
- ✅ Add missing features (clustering, culling)
-
Medium-term (3-6 months):
- ⚠️ Monitor library health
- ⚠️ Test Leaflet with React 19
- ⚠️ Prepare migration plan
-
Long-term (if needed):
- 🔄 Migrate to Leaflet if current library becomes problematic
Why this approach:
- Minimizes immediate effort
- Gets you a working solution quickly
- Provides escape hatch if library fails
- Allows you to evaluate Leaflet React 19 support
Migration Checklist (If Needed)
If you decide to migrate to Leaflet:
- Install
react-leafletandleaflet - Create new
LeafletMapcomponent - Migrate GeoJSON rendering
- Migrate marker rendering
- Migrate connection lines
- Migrate zoom/pan controls
- Add clustering plugin
- Test performance
- Update documentation
- Remove old library
Estimated effort: 8-12 hours
Conclusion
My recommendation: Keep the current library for now, but fix the critical bugs and add performance optimizations. This gives you a working solution with minimal effort. Then, monitor the library's health and prepare a migration to Leaflet if needed.
The current library is sufficient for your use case, but Leaflet would be more reliable long-term. The hybrid approach gives you the best of both worlds: quick fixes now, reliable option later.