Terra Draw - Bring drawing feature to all map applications

Jin Igarashi
3 September 2026, 14:30
International Conference Center Hiroshima
FOSS4G 2026 Hiroshima

Jin Igarashi

Software Engineer, Fracta Inc

linkedinlinkedin.com/in/jinigarashi
githubgithub.com/JinIgarashi
Jin Igarashi

What is Terra Draw

An introduction for newcomers

Drawing on a web map looks simple

Until you have to build it.

  • Click to add a vertex, drag to move it, snap it to its neighbour
  • Keep the geometry valid while the user is still drawing
  • Undo, redo, select, delete
  • Then do it all again on the next mapping library

Every map library had its own answer

Existing drawing plugins

Leaflet.draw, leaflet-freedraw, mapbox-gl-draw... different APIs, different
behaviour, different bugs — and your drawing code is locked to one map.

Terra Draw

An open source TypeScript library for drawing on web maps, created by
James Milner about four years ago.

One drawing engine, many maps.

npm install terra-draw

Goals

  • Cross map library support
  • Custom modes
  • Deep styling control
  • Zero dependencies

How it fits together

Terra Draw architecture

Adapter talks to the map · Modes own the interaction · Store holds
the GeoJSON.

One API, many maps

Supported map libraries

Swap the adapter, keep everything else.

Modes do the drawing

  • point, linestring, polygon, marker, polyline
  • rectangle, angled-rectangle, circle, sector, sensor
  • freehand, freehand-linestring
  • select — move, rotate, scale, delete
  • ...or write your own

Getting Started

What does TerraDraw help you achieve?

Set up in a few lines

import { TerraDraw, TerraDrawPolygonMode } from 'terra-draw';
import { TerraDrawMapLibreGLAdapter } from 'terra-draw-maplibre-gl-adapter';

const draw = new TerraDraw({
  adapter: new TerraDrawMapLibreGLAdapter({ map }),
  modes: [new TerraDrawPolygonMode({ snapping: true })]
});

draw.start();
draw.setMode('polygon');

The data is just GeoJSON

draw.on('finish', (id) => {
  const snapshot = draw.getSnapshot();
  const feature = snapshot.find((f) => f.id === id);
  console.log(JSON.stringify(feature));
});

getSnapshot() / addFeatures() — load, save and round-trip your features
with anything that speaks GeoJSON.

What's new for 2026?

New features to use in your project

Undo / redo

Undo and redo buttons

Common in every drawing application, one of the most requested features — and
hard to get right.

A two-part system

  • Drawing undo / redo, which works inside a single mode
  • Session undo / redo, which works across modes
  • Use them together, or either one on its own
draw.undo();
draw.redo();

Styling improvements

Per-feature styling

New ways to style your geometries — style callbacks receive the feature, so
colour, width and opacity can depend on your own properties.

Per-feature styling

line mode now supports dashed lines, with a new lineStringDash style property.

Polyline mode

Polyline mode

Lines that can be closed into polygons: start drawing a line and finish it as
an area, without switching mode.

Multiple instances of the same mode

Two polygon modes with different styles

Register one mode twice with different configurations — for example two polygon
modes with different styling and validation.

New drawing interactions

Click and drag drawing

Click and drag support: drag out a rectangle or a circle in one gesture instead
of clicking corner by corner.

But you still have to build the UI

Terra Draw gives you the drawing engine — the buttons, the mode switching and
the map controls are yours to write.

maplibre-gl-terradraw

A MapLibre GL JS plugin: Terra Draw plus a ready-made control.

One line to add the control

npm install @watergis/maplibre-gl-terradraw

Then, just one line of code to add the control to your MapLibre map:

import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw';

map.addControl(
  new MaplibreTerradrawControl({ open: true }),
  'top-left'
);

Measure control

Measure control

MaplibreMeasureControl adds distance and area labels to the geometries as
you draw them.

Routing with the Valhalla control

Valhalla control

Draw a line, get a route back — the isochrone and routing controls turn drawn
geometry into an API request.

An example - UNDP's GeoHub

GeoHub drawing and measuring on a MapLibre map

UNDP's GeoHub uses the plugin for drawing and measuring.

terra-draw-cesium-adapter

A CesiumJS adapter for Terra Draw was released last week heading into FOSS4G 2026.

Drawing on a 3D globe

Terra Draw drawing on a CesiumJS 3D globe

The same modes and the same GeoJSON — running on CesiumJS.

npm i @watergis/terra-draw-cesium-adapter

Contribution

How you can get involved with the Terra Draw project

Contributing

  • Lend a star on GitHub
  • If you find a bug, post a clear reproducible issue
  • Discuss issues on the tracker, and raise pull requests
  • Let's chat after the talk if you are interested!

Links and resources

  • Terra Draw — https://terradraw.io · https://github.com/JamesLMilner/terra-draw
  • Terra Draw Cesium Adapter — github.com/watergis/terra-draw-cesium-adapter
  • Plugin — https://terradraw.water-gis.com
  • Workshop material - https://workshops.terradraw.water-gis.com

Questions?

Thank you for listening