Get Started
Installation
npm install @deck.gl-community/editable-layers
You'll also need deck.gl and a base map provider:
npm install deck.gl @deck.gl/react @deck.gl/core @deck.gl/layers maplibre-gl react-map-gl
Quick Overview of the API
EditableGeoJsonLayer
EditableGeoJsonLayer is implemented as a deck.gl layer. It provides the ability to view and edit multiple types of geometry formatted as GeoJSON (an open standard format for geometry) including polygons, lines, and points.
Edit Modes
Edit modes control how the user interacts with features. Each mode defines a specific editing behavior:
- View modes:
ViewMode— Select features without editing - Draw modes:
DrawPointMode,DrawLineStringMode,DrawPolygonMode,DrawRectangleMode,DrawCircleFromCenterMode, and more — Create new geometry by clicking on the map - Transform modes:
ModifyMode,TranslateMode,RotateMode,ScaleMode— Modify existing geometry by dragging vertices or features - Measurement modes:
MeasureDistanceMode,MeasureAreaMode,MeasureAngleMode— Measure distances, areas, and angles - Composite modes:
CompositeMode,SnappableMode— Combine multiple modes or add snapping behavior
Set the mode via the mode prop on EditableGeoJsonLayer. See the Edit Modes API reference for the full list.
Callbacks
When editing is enabled, the onEdit callback fires with details about each edit:
onEdit: ({updatedData, editType, editContext}) => {
// updatedData — the new FeatureCollection after the edit
// editType — 'addFeature', 'movePosition', 'removePosition', etc.
// editContext — mode-specific context (e.g. featureIndexes for addFeature)
setFeatures(updatedData);
}
Minimal Example
import React, {useState} from 'react';
import DeckGL from '@deck.gl/react';
import {
EditableGeoJsonLayer,
DrawPolygonMode,
ViewMode
} from '@deck.gl-community/editable-layers';
import StaticMap from 'react-map-gl/maplibre';
const INITIAL_VIEW_STATE = {
longitude: -122.43,
latitude: 37.775,
zoom: 12
};
export function GeometryEditor() {
const [features, setFeatures] = useState({
type: 'FeatureCollection',
features: []
});
const [mode, setMode] = useState(() => DrawPolygonMode);
const [selectedFeatureIndexes, setSelectedFeatureIndexes] = useState([]);
const layer = new EditableGeoJsonLayer({
data: features,
mode,
selectedFeatureIndexes,
onEdit: ({updatedData}) => {
setFeatures(updatedData);
}
});
return (
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={{doubleClickZoom: false}}
layers={[layer]}
getCursor={layer.getCursor.bind(layer)}
>
<StaticMap mapStyle="https://tiles.openfreemap.org/styles/positron" />
</DeckGL>
);
}
See the getting-started example for a complete runnable version.
MapLibre and Mapbox Interleaved Editing
With MapboxOverlay({interleaved: true}), handle drags and drag-to-draw gestures do not pan
the MapLibre/Mapbox map; other mouse presses pan and click it. Use ViewMode to navigate or set
autoPreventMapInteractions: false to manage gesture propagation yourself. Multi-touch
navigation and the map's configured controls remain available.
const overlay = new MapboxOverlay({
interleaved: true,
layers: [new EditableGeoJsonLayer({
id: 'editable',
data,
mode: DrawPolygonMode,
selectedFeatureIndexes: [],
onEdit: ({updatedData}) => updateData(updatedData)
})]
});
map.addControl(overlay);
MapLibre and Mapbox Overlaid Editing
With MapboxOverlay({interleaved: false}), set eventTarget: map.getCanvas() on editable
and selection layers. Interleaved overlays use the shared canvas automatically.
const overlay = new MapboxOverlay({
interleaved: false,
layers: [new EditableGeoJsonLayer({
id: 'editable',
data,
mode: DrawPolygonMode,
eventTarget: map.getCanvas(),
selectedFeatureIndexes: [],
onEdit: ({updatedData}) => updateData(updatedData)
})]
});
map.addControl(overlay);
Widgets
editable-layers ships deck.gl widgets that provide editing UI without requiring you to build custom React components.
EditModeTrayWidget
Renders a tray of mode selection buttons. Pass it to the widgets prop on your DeckGL component:
import {EditModeTrayWidget, ViewMode, DrawPolygonMode} from '@deck.gl-community/editable-layers';
const trayWidget = new EditModeTrayWidget({
placement: 'top-left',
layout: 'vertical',
modes: [
{id: 'view', mode: ViewMode, label: 'View'},
{id: 'draw-polygon', mode: DrawPolygonMode, label: 'Polygon'}
],
onSelectMode: ({mode}) => setMode(mode)
});
<DeckGL widgets={[trayWidget]} ... />
EditorToolbarWidget
Renders a toolbar with boolean operations (union, difference, intersection), clear, and export buttons:
import {EditorToolbarWidget} from '@deck.gl-community/editable-layers';
const toolbarWidget = new EditorToolbarWidget({
placement: 'bottom-left',
onSetBooleanOperation: (op) => setModeConfig(op ? {booleanOperation: op} : {}),
onClear: () => setFeatures({type: 'FeatureCollection', features: []}),
onExport: () => downloadGeoJson(features)
});
See the editor example for a full widgets-only editing setup, and the Widget API docs for the complete props reference.