A powerful React component for integrating Leaflet maps with support for markers, polygons, polylines, circles, and rectangles.
npm install @gcampra/react-native-leaflet

A powerful React component to integrate Leaflet maps with complete support for markers, polygons, polylines, circles, and rectangles. Developed following the same philosophy and approach of the laravel-leaflet project.
!React Native Leaflet in action
- πΊοΈ Complete Leaflet integration
- π Support for Markers
- π· Support for Polygons
- π Support for Polylines
- β Support for Circles
- β Support for Rectangles
- π― Complete TypeScript with well-defined types
- βοΈ Highly configurable and extensible
- π¦ Ready for npm publication
- π§ Custom hooks for map control
``bash`
npm install react-native-leaflet leaflet
or with yarn:
`bash`
yarn add react-native-leaflet leaflet
`jsx
import React from 'react';
import { LeafletMap } from 'react-native-leaflet';
function App() {
const mapOptions = {
center: {
lat: -23.347509,
lng: -47.847536
},
zoom: 18,
height: '600px',
width: '100%'
};
const markers = [
{
position: {
lat: -23.347509,
lng: -47.847536
},
title: 'My Marker',
popupContent: 'This is an example marker'
}
];
return (
options={mapOptions}
initialMarkers={markers}
/>
);
}
export default App;
`
`jsx
import React from 'react';
import { LeafletMap } from 'react-native-leaflet';
function AdvancedMap() {
const mapOptions = {
center: {
lat: -23.347509,
lng: -47.847536
},
zoom: 18,
zoomControl: true,
minZoom: 13,
maxZoom: 18,
height: '600px',
draggable: true,
googleview: true
};
const markers = [
{
position: {
lat: -23.347509,
lng: -47.847536
},
draggable: false,
title: 'TatuΓ - SP'
}
];
const polygons = [
{
positions: [
{ lat: -23.34606, lng: -47.84818 },
{ lat: -23.34575, lng: -47.84759 },
{ lat: -23.34615, lng: -47.84729 },
{ lat: -23.34651, lng: -47.84792 }
],
color: '#3388ff',
fillColor: '#3388ff',
fillOpacity: 0.2
}
];
const polylines = [
{
positions: [
{ lat: -23.348914, lng: -47.850147 },
{ lat: -23.347850, lng: -47.848109 },
{ lat: -23.349209, lng: -47.847293 },
{ lat: -23.347781, lng: -47.844675 }
],
color: '#ff0000',
weight: 3
}
];
const circles = [
{
position: {
lat: -23.346569,
lng: -47.843763
},
radius: 80,
color: '#00ff00',
fillOpacity: 0.3
}
];
return (
options={mapOptions}
initialMarkers={markers}
initialPolygons={polygons}
initialPolylines={polylines}
initialCircles={circles}
onMarkerClick={(marker, index) => console.log('Marker clicked:', marker)}
onPolygonClick={(polygon, index) => console.log('Polygon clicked:', polygon)}
/>
);
}
export default AdvancedMap;
`
`jsx
import React, { useRef } from 'react';
import { LeafletMap } from 'react-native-leaflet';
function MapWithControls() {
const mapRef = useRef();
const handleFitBounds = () => {
mapRef.current?.fitBounds();
};
const handleSetCenter = () => {
mapRef.current?.setCenter({
lat: -23.5505,
lng: -46.6333
}, 15);
};
const mapOptions = {
center: {
lat: -23.347509,
lng: -47.847536
},
zoom: 18
};
return (
export default MapWithControls;
`
| Prop | Type | Required | Description |
|------|------|----------|------------|
| options | MapOptions | Yes | Map configuration options |title
| | string | No | Map title |initialMarkers
| | Marker[] | No | Array of initial markers |initialPolygons
| | Polygon[] | No | Array of initial polygons |initialPolylines
| | Polyline[] | No | Array of initial polylines |initialCircles
| | Circle[] | No | Array of initial circles |initialRectangles
| | Rectangle[] | No | Array of initial rectangles |onMapReady
| | (map: L.Map) => void | No | Callback when map is ready |onMarkerClick
| | (marker: Marker, index: number) => void | No | Callback when marker is clicked |onPolygonClick
| | (polygon: Polygon, index: number) => void | No | Callback when polygon is clicked |onPolylineClick
| | (polyline: Polyline, index: number) => void | No | Callback when polyline is clicked |onCircleClick
| | (circle: Circle, index: number) => void | No | Callback when circle is clicked |onRectangleClick
| | (rectangle: Rectangle, index: number) => void | No | Callback when rectangle is clicked |className
| | string | No | Custom CSS class |containerStyle
| | React.CSSProperties | No | Custom container styles |
`typescript`
interface MapOptions {
center: Position; // Initial map position
zoom: number; // Initial zoom level
zoomControl?: boolean; // Show zoom controls (default: true)
minZoom?: number; // Minimum zoom
maxZoom?: number; // Maximum zoom
width?: string; // Map width (default: "100%")
height?: string; // Map height (default: "600px")
draggable?: boolean; // Allow dragging map (default: true)
touchZoom?: boolean; // Touch zoom (default: true)
scrollWheelZoom?: boolean; // Zoom with mouse wheel (default: true)
doubleClickZoom?: boolean; // Zoom with double click (default: true)
boxZoom?: boolean; // Box zoom (default: true)
keyboard?: boolean; // Keyboard controls (default: true)
googleview?: boolean; // Add Google Street View (default: false)
}
`typescript`
interface Marker {
position: Position;
title?: string;
draggable?: boolean;
icon?: string;
popupContent?: string;
onClick?: () => void;
}
You can access the following methods through the component ref:
`typescript
const mapRef = useRef();
// Add marker programmatically
mapRef.current.addMarker(marker);
// Remove marker by index
mapRef.current.removeMarker(0);
// Fit zoom to show all elements
mapRef.current.fitBounds();
// Get map center
const center = mapRef.current.getCenter();
// Set new center
mapRef.current.setCenter({ lat: -23.5505, lng: -46.6333 }, 15);
// Get Leaflet instance
const map = mapRef.current.map;
`
`typescript
import {
calculateDistance,
getCenterPoint,
formatPosition,
isPositionInBounds
} from 'react-native-leaflet';
// Calculate distance between two points (in meters)
const distance = calculateDistance(pos1, pos2);
// Get center point of multiple positions
const center = getCenterPoint(positions);
// Format position for display
const formatted = formatPosition(position, 6);
// Check if position is within bounds
const inBounds = isPositionInBounds(position, [minLat, minLng, maxLat, maxLng]);
`
``
react-native-leaflet/
βββ src/
β βββ LeafletMap.tsx # Main component
β βββ types.ts # Type definitions
β βββ hooks.ts # Custom hooks
β βββ utils.ts # Utility functions
β βββ index.ts # Main exports
βββ dist/ # Compiled build
βββ package.json
βββ tsconfig.json
βββ rollup.config.js
βββ README.md
βββ LICENSE.md
`bashBuild the project
npm run build
Compatibility
- React 16.8+
- Leaflet 1.7.0+
- Node.js 14+
License
MIT License Β© 2025 - See LICENSE.md for details.
Contributing
Contributions are welcome! Please:
1. Fork the project
2. Create a branch for your feature (
git checkout -b feature/AmazingFeature)
3. Commit your changes (git commit -m 'Add some AmazingFeature')
4. Push to the branch (git push origin feature/AmazingFeature`)To report issues or suggest improvements, open an issue.
This project was developed following the same philosophy and approach of the excellent laravel-leaflet project by @ginocampra, adapting its concepts for the React ecosystem.