COMPARE
Element Editor vs Leaflet.Draw
Leaflet.Draw's last release was in 2018. Element is what you'd build if you started from scratch today.
Why this comparison exists
You landed on Leaflet.Draw because it's the first result for "leaflet drawing". Then you looked at the README — Travis CI and Bower badges, and a usage example with CloudMade tiles (CloudMade ended its public tile service in 2014). You checked the release history: the last version, 1.0.4, shipped in October 2018. You're looking for an alternative now.
Fair enough. Here's an honest comparison.
Feature comparison
| Capability | Leaflet.Draw | Element |
|---|---|---|
| Drawing: polygon, line, rectangle, circle, marker / point | Included | Included |
| Freehand drawing | Not included | Included |
| Road-snapped route | Not included | Included |
| Vertex editing | Included | Included |
| Snapping | Not included | Included |
| Transform (scale, rotate) | Not included | Included |
| Boolean operations (union, intersect, subtract, cut hole, slice) | Not included | Included |
| Geometry processing (buffer, simplify, smooth, break apart, merge) | Not included | Included |
| Measure (distance, area) | Includedtooltip while drawing | Included |
| Schema-backed properties (typed fields) | Not included | Included |
| In-app schema editor | Not included | Included |
| Data table with inline editing | Not included | Included |
| Two-way GeoJSON editor | Not included | Included |
| Keyboard shortcuts (remappable) | Not included | Included |
| TypeScript, first-class | Community types (@types/leaflet-draw) | Included |
| React component | Third-party (react-leaflet-draw) | Included@element-editor/react/leaflet on Leaflet, @element-editor/react on MapLibre |
| MapLibre adapter | Not included | Included |
| Actively maintained | Not included | Included |
| Latest release | 1.0.4 (October 2018) | Pre-1.0, in active development |
Migration: from L.Control.Draw to Element
Before — Leaflet.Draw:
const editableLayers = new L.FeatureGroup()
map.addLayer(editableLayers)
const drawControl = new L.Control.Draw({
position: 'topright',
draw: {
polygon: { allowIntersection: false },
circle: false,
marker: { icon: new L.Icon.Default() },
},
edit: {
featureGroup: editableLayers,
},
})
map.addControl(drawControl)
map.on(L.Draw.Event.CREATED, (e) => {
editableLayers.addLayer(e.layer)
})After — Element with @element-editor/adapter-leaflet:
import { MapContainer, TileLayer } from 'react-leaflet'
import {
ElementEditorUIProvider, GeoStoreProvider, ElementEditorControls,
FloatingToolbar, EditingToolbar, ActiveDrawingToolbar,
} from '@element-editor/adapter-leaflet'
import '@element-editor/adapter-leaflet/style.css'
export default function MyMap() {
return (
<ElementEditorUIProvider>
<GeoStoreProvider>
<div data-elm-theme="light" style={{ position: 'relative', height: 600 }}>
<MapContainer center={[48.86, 2.35]} zoom={12} style={{ height: '100%' }}>
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
<ElementEditorControls
tools={['polygon', 'line', 'point', 'rectangle']}
onChange={(data) => console.log(data)}
/>
</MapContainer>
<FloatingToolbar />
<EditingToolbar />
<ActiveDrawingToolbar />
</div>
</GeoStoreProvider>
</ElementEditorUIProvider>
)
}The shape changes from imperative (L.Control.Draw constructor + event listeners) to declarative (a React component with props and callbacks). Output is still standard GeoJSON.
When Leaflet.Draw is still the right choice
Honest section. Leaflet.Draw isn't wrong for every case:
- You're not using React. Leaflet.Draw is plain JS; it fits pure-Leaflet codebases with no framework overhead. Element's Leaflet adapter needs React 19.2+ and react-leaflet, which a framework-free codebase may not want.
- You need the minimal possible footprint. Leaflet.Draw is about 15 KB gzipped (script and stylesheet). Element is larger because it does more — snapping, transform, schemas, etc. The Leaflet drop-in loads about 272 KB of gzipped JavaScript, React and Leaflet included.
- Your integration is already working. If Leaflet.Draw has been stable in your codebase for years, the migration cost has to be weighed against the benefit. There's no urgency unless you need features Element adds.
What you get with Element that Leaflet.Draw doesn't
- React, first-class.
@element-editor/react/leafletis a drop-in component for Leaflet (the default@element-editor/reactentry runs on MapLibre). NoL.Controlimperative setup, no event listener bookkeeping, no ref juggling. - TypeScript, first-class. Element's types ship in its packages; no third-party typings for the editor (Leaflet itself still takes
@types/leaflet). - Snapping, boolean operations, geometry processing. All of these are new capabilities, not stylistic choices.
- A data layer. Schemas, a data table, a GeoJSON editor. Things Leaflet.Draw never attempted.
- Active development. Every change is recorded in the changelog.
Frequently asked
Is Leaflet.Draw still maintained? The last release, 1.0.4, was published in October 2018, and its default branch has had no commits since September 2018. The repository isn't archived, but there's no active feature development. The README still shows a CloudMade tile example; CloudMade ended its public tile service in 2014.
Can I migrate from Leaflet.Draw to Element gradually?
Yes, once your map is rendered with react-leaflet. ElementEditorControls from @element-editor/adapter-leaflet mounts inside the same MapContainer, so L.Control.Draw can stay on that map during the transition. Remove Leaflet.Draw once you've migrated every feature.
Does Element support the same tools as Leaflet.Draw? Yes, and more. Element ships area (polygon), line, point, rectangle, circle, freehand, road-snapped route, plus a Picker that imports shapes straight from OpenStreetMap. Every tool has a default keyboard shortcut; every shortcut is remappable.
Is Element free to use? Yes. Everything Element ships today is MIT-licensed and free for any use, including commercial. That covers drawing, editing, selection, transform, snapping, boolean operations, geometry processing, schemas, the data table, and the GeoJSON editor — all of it.