Geo shape

The geo shape is one of the default shapes in tldraw. It renders geometric primitives with optional text labels. Geo shapes support 20 different geometric forms—from basic shapes like rectangles and ellipses to specialized forms like stars, clouds, and directional arrows. They can display rich text labels with configurable alignment. These capabilities make geo shapes the foundation for flowcharts, diagrams, and annotated illustrations.

Geometric forms

The geo shape supports a variety of built-in forms, grouped by type:

Basic shapes

FormDescription
rectangleFour-sided shape with right angles (default)
ellipseOval or circular shape
triangleThree-sided shape pointing upward
diamondSquare rotated 45 degrees
ovalStadium shape (rectangle with rounded ends)

Polygons

FormDescription
pentagonFive-sided regular polygon
hexagonSix-sided regular polygon
octagonEight-sided regular polygon
starFive-pointed star

Parallelograms

FormDescription
rhombusParallelogram slanted to the right
rhombus-2Parallelogram slanted to the left
trapezoidFour-sided shape with parallel top and bottom

Directional arrows

FormDescription
arrow-upBlock arrow pointing upward
arrow-downBlock arrow pointing downward
arrow-leftBlock arrow pointing left
arrow-rightBlock arrow pointing right

Special shapes

FormDescription
cloudOrganic cloud shape with randomly varied bumps
heartHeart shape
x-boxRectangle with an X through it
check-boxRectangle with a checkmark inside

Creating geo shapes

Create a geo shape using Editor.createShape:

import { toRichText } from 'tldraw'

editor.createShape({
	type: 'geo',
	x: 100,
	y: 100,
	props: {
		geo: 'rectangle',
		w: 200,
		h: 150,
		color: 'blue',
		fill: 'solid',
		dash: 'draw',
		size: 'm',
	},
})

Adding text labels

Geo shapes support rich text labels positioned inside the shape:

editor.createShape({
	type: 'geo',
	x: 100,
	y: 100,
	props: {
		geo: 'ellipse',
		w: 200,
		h: 150,
		richText: toRichText('Process step'),
		labelColor: 'black',
		align: 'middle',
		verticalAlign: 'middle',
		font: 'draw',
	},
})

The label text automatically wraps within the shape bounds. When text overflows the shape height, the shape grows vertically to accommodate it. The growY property tracks this additional height.

Changing the geometric form

Switch between forms by updating the geo property:

// Change a rectangle to an ellipse
editor.updateShape({
	id: shapeId,
	type: 'geo',
	props: {
		geo: 'ellipse',
	},
})

You can also set the default geometric form for the geo tool by updating the style for the next shape:

import { GeoShapeGeoStyle } from 'tldraw'

// Set the default geo style to star
editor.setStyleForNextShapes(GeoShapeGeoStyle, 'star')

Using the geo tool

The geo tool creates shapes through click or click-and-drag interactions.

Click to create

Click anywhere on the canvas to create a shape at the default size. The shape centers on your click position. Different geometric forms have different default sizes:

FormDefault size
star200 × 190
cloud300 × 180
Other200 × 200

Click and drag to create

Click and drag to create a shape at a custom size. The shape's corner follows your pointer as you drag. Release to complete the shape.

Editing labels

Press Enter while a geo shape is selected to edit its label. The shape enters edit mode, allowing you to type or modify the rich text content. Press Escape to exit edit mode.

Tool lock

When tool lock is enabled (via the toolbar or Editor.setCurrentTool), you can create multiple shapes without returning to the select tool after each one.

Shape properties

PropertyTypeDescription
geoTLGeoShapeGeoStyleThe geometric form
wnumberWidth in pixels
hnumberHeight in pixels
richTextTLRichTextText label displayed inside the shape
colorTLDefaultColorStyleStroke/outline color
labelColorTLDefaultColorStyleText label color (separate from stroke)
fillTLDefaultFillStyleFill style: none, semi, solid, pattern
dashTLDefaultDashStyleStroke pattern: draw, solid, dashed, dotted
sizeTLDefaultSizeStyleSize preset affecting stroke width
fontTLDefaultFontStyleFont family for the label
alignTLDefaultHorizontalAlignStyleHorizontal text alignment
verticalAlignTLDefaultVerticalAlignStyleVertical text alignment
growYnumberAdditional vertical space for text overflow
urlstringOptional hyperlink URL
scalenumberScale factor applied to the shape

Configuration options

Configure the geo shape utility to adjust rendering behavior:

OptionTypeDefaultDescription
showTextOutlinebooleantrueWhether to show a text outline (using the canvas background color) to improve label readability.
import { GeoShapeUtil } from 'tldraw'

const ConfiguredGeoUtil = GeoShapeUtil.configure({
	showTextOutline: false,
})

Pass the configured utility to the shapeUtils prop:

<Tldraw shapeUtils={[ConfiguredGeoUtil]} />

Label positioning

The align and verticalAlign properties control where labels appear within the shape:

Horizontal alignment

ValuePosition
startLeft edge of shape
middleHorizontally centered
endRight edge of shape

Vertical alignment

ValuePosition
startTop of shape
middleVertically centered
endBottom of shape

When the label text exceeds the shape's height, the shape automatically grows by adding to growY. The shape never shrinks below its original h value to accommodate shorter text—instead, growY returns to 0.

Resizing behavior

Geo shapes resize from any corner or edge handle. When resizing a shape with a label:

  • The shape respects a minimum unscaled size of 51 × 51 pixels when it contains text
  • The shape won't shrink smaller than the label's required dimensions
  • growY resets to 0 when you resize, letting the shape recalculate the needed height

Special interactions

Rectangle/checkbox toggle

Double-click a rectangle while holding Alt to convert it to a checkbox. Double-click the checkbox with Alt held to convert it back to a rectangle. This lets you quickly add checkmarks to items.

Cloud shape variation

The cloud shape generates its bumps procedurally based on the shape's ID. Each cloud has unique bump positions, giving visual variety while maintaining a consistent style. Larger clouds have more bumps; smaller clouds have fewer but at least six.

Handle snap geometry

Arrows snap to geo shapes at meaningful positions:

  • Polygon-based shapes (rectangle, triangle, pentagon, etc.): Arrows snap to each vertex and the center
  • Curved shapes (ellipse, oval, cloud, heart): Arrows snap only to the center point

Dynamic resize mode

When dynamic resize mode is enabled in user preferences, new geo shapes scale inversely with zoom level. Drawing while zoomed out creates shapes that appear the same size on screen as they would at 100% zoom.

// Enable dynamic resize mode
editor.user.updateUserPreferences({ isDynamicResizeMode: true })

Geo shapes can link to URLs. When a shape has a URL, a link button appears on the shape:

editor.createShape({
	type: 'geo',
	x: 100,
	y: 100,
	props: {
		geo: 'rectangle',
		w: 200,
		h: 100,
		url: 'https://tldraw.dev',
	},
})

Click the link button to open the URL in a new tab.

Path rendering

Geo shapes use a path-based rendering system. Each geometric form has a corresponding path definition in getGeoShapePath, which generates the outline used for both fill rendering and stroke styles. The path system supports:

  • Fill rendering: Solid, semi-transparent, or pattern fills
  • Stroke styles: Solid lines, dashed patterns, dotted patterns, and hand-drawn "draw" style
  • Efficient caching: Path calculations are cached per shape instance

When the dash property is set to 'draw', the shape renders with organic, hand-drawn strokes that vary slightly based on the shape's position and size.

Geometry

The shape's geometry returns a Group2d containing:

  1. The outline path geometry (polygon or curve depending on the form)
  2. A label rectangle for hit testing text interactions

This compound geometry enables accurate point-in-shape detection for both the shape outline and its text label.

  • Default shapes — Overview of all built-in shapes
  • Rich text — Working with formatted text content
  • Styles — Working with shape styles like color and fill
  • Tools — How tools handle user input
Prev
Focus
Next
Geometry