GeoJSON with Leaflet.js
Leaflet's L.geoJSON() function turns a GeoJSON object into a map layer in four lines.
L.geoJSON takes a GeoJSON Feature, FeatureCollection, or bare geometry object and converts it to the appropriate Leaflet layer type: Marker for Points, Polyline for LineStrings, Polygon for Polygons, and so on. The result is added to the map just like any other layer — no parsing, no manual geometry translation.
Load and render
import L from 'leaflet'
const map = L.map('map').setView([51.5074, -0.1276], 12)
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map)
const data = await fetch('/features.geojson').then(r => r.json())
L.geoJSON(data).addTo(map)L.map('map') attaches Leaflet to the element with id="map". setView takes [latitude, longitude] — note the order differs from GeoJSON coordinates, which use [longitude, latitude]. fetch returns a Response object; .then(r => r.json()) parses it to a plain JavaScript object before passing it to L.geoJSON.
The layer renders immediately with Leaflet's default styles: blue strokes for lines and polygons, blue markers for points.
Per-feature styling
L.geoJSON(data, {
style: (feature) => ({
color: feature.properties.type === 'park' ? '#2d9e6b' : '#3388ff',
weight: 2,
fillOpacity: 0.4,
}),
}).addTo(map)The style option receives each feature and returns a Path options object. color sets both stroke and fill colour unless fillColor is set separately. weight is stroke width in pixels. fillOpacity ranges from 0 (transparent) to 1 (opaque).
The style function only applies to vector layers (polygons, lines). For point features, use pointToLayer to create a custom marker instead.
Popups on click
L.geoJSON(data, {
onEachFeature: (feature, layer) => {
if (feature.properties?.name) {
layer.bindPopup(feature.properties.name)
}
},
}).addTo(map)onEachFeature runs once per feature after the layer is created. layer.bindPopup attaches a popup that opens when the user clicks the feature. The popup content is a string — you can pass HTML for richer content: layer.bindPopup('<strong>' + feature.properties.name + '</strong>').
The optional-chaining check (feature.properties?.name) guards against features with null properties, which RFC 7946 allows.
Filtering features
L.geoJSON(data, {
filter: (feature) => feature.properties.visible !== false,
}).addTo(map)The filter option runs before each feature is added. Return true to include the feature, false to skip it. This is applied at render time — it does not mutate the original data object. To update which features are visible, remove the layer and call L.geoJSON again with a new filter.
React-Leaflet
import { MapContainer, TileLayer, GeoJSON } from 'react-leaflet'
import type { FeatureCollection } from 'geojson'
const data: FeatureCollection = { type: 'FeatureCollection', features: [...] }
export function MyMap() {
return (
<MapContainer center={[51.5074, -0.1276]} zoom={12} style={{ height: 400 }}>
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
<GeoJSON data={data} />
</MapContainer>
)
}react-leaflet's <GeoJSON> component wraps L.geoJSON and accepts the same options as props: style, onEachFeature, filter, pointToLayer. The FeatureCollection type is from the geojson npm package, which ships TypeScript declarations for all GeoJSON object types.
One caveat: <GeoJSON> does not update when the data prop changes reference. If your data changes at runtime, pass a new key prop to force a full remount:
<GeoJSON key={JSON.stringify(data)} data={data} />Watch out:
L.geoJSONaccepts a plain JavaScript object, not a JSON string. If you're usingfetch, call.then(r => r.json())to parse before passing to Leaflet. Passing a string produces a silent empty layer.
Editing GeoJSON on a Leaflet map
Rendering GeoJSON in Leaflet is one line. Drawing and editing it — adding vertices, moving shapes, cutting holes — requires an editing layer. @element-editor/adapter-leaflet is an open-source MIT library that adds drawing and editing to an existing react-leaflet map without replacing your Leaflet setup.
For GeoJSON format reference, see What is GeoJSON?. For React-specific patterns, see GeoJSON with React.
Continue reading
- GeoJSON with React
How to load and render GeoJSON in React — with react-leaflet, react-map-gl, state management for selected features, and the useMemo trap.
- GeoJSON with Mapbox GL JS
How to add a GeoJSON source to Mapbox GL JS, render it as fill, line, or circle layers, update it at runtime, and filter by property.
- FoundationsWhat is GeoJSON?
GeoJSON is an open standard (RFC 7946) for encoding geographic features as JSON. Learn the format, geometry types, and how it's used.

Mike Acler
Design engineer and creator of Element Editor, an open-source map drawing and GeoJSON editing library for React. Writes about web cartography and GIS tooling.