Learn / Edges & routing

Edges & routing

An edge stores intent — connect A to B, orthogonally, avoiding obstacles — and the renderer turns intent into geometry that stays correct as nodes move. Only two fields are required.

The minimal edge, and every field after it

{ source: 'a', target: 'b' }                       // that's a complete edge

{ id: 'e1',
  source: 'a', target: 'b',                          // node ids
  sourceHandle: 'out',                               // a port id — or a bare side: 'right'
  targetHandle: 'left',
  type: 'orthogonal',                                // 'direct' | 'smooth' | 'orthogonal' | 'bezier'
  router: 'avoid',                                   // 'straight' | 'orthogonal' | 'manhattan' | 'avoid' | 'elk'
  connector: 'rounded',                              // corner treatment: 'straight' | 'rounded' | 'smooth' | 'bezier'
  label: 'retry',
  style: { stroke: '#9333ea', strokeWidth: 2, strokeDasharray: '6 3' },
  data: { weight: 3 },                               // your payload
  points: [{ x: 340, y: 180 }] }                     // explicit waypoints — restores a user-edited route

Omit both handles and the edge attaches to whichever default port faces its partner as nodes move. Default ports have deterministic ids (<nodeId>__top__left), which is why a bare side name like sourceHandle: 'bottom' resolves. For true perimeter floating — attaching anywhere along the node's outline rather than at a port — set metadata: { connectionPoint: 'smart' }.

Type versus router — two different questions

type answers "what shape is the line" (straight segments, one smooth curve, right angles, a bezier). router answers "which path does it take" — and that is where the interesting engineering lives:

RouterBehavior
straightdirect line, endpoints only
orthogonalright-angled path from the port's exit direction
manhattangrid-based right-angle routing with turn minimization
avoidobstacle avoidance — the path walks around nodes instead of crossing them, and re-routes live as you drag
elkedge routes computed by the ELK layout engine, consistent with an ELK-laid-out graph
Obstacle-avoiding routing is the feature most diagram libraries sell as a paid add-on or leave as an exercise. Here it is one word on the edge spec. The comparison table sources this cell by cell.

Live: every edge type, router and connector →

Labels, parallel edges, crossings

label puts editable text on the path (double-click to edit in place; drag to reposition — the position persists in the model). When several edges connect the same pair of nodes, the renderer fans them apart (rendererConfig: { parallelLinks: true, parallelSpacing: 12 }), and where unrelated edges cross you can render jump-overs via the renderer config's jump styles.

Reconnecting and editing

Drag an edge's endpoint and drop it on another port — validators run again (see Ports & validation; the candidate carries link so a rule can treat reconnection differently). Drag the path itself to bend it — the bend lands in points and round-trips through serialization. Every one of these edits is a single undoable step.

Where next