Skip to content

FlowChart API reference

This page lists the public surface of @flowgl/core. The same surface is exposed through the framework wrappers — methods become wrapper-component ref handles, events become callback props (React) / emits (Vue) / on: directives (Svelte).

Wrapper-specific shapes:

Constructor

ts
new FlowChart(options: FlowChartOptions)

FlowChartOptions

OptionTypeDefaultDescription
containerHTMLElementRequired. The chart canvas + overlays mount inside this element.
nodesNodeData[][]Initial nodes.
edgesEdgeData[][]Initial edges.
rendererKind'webgl2' | 'canvas2d' | Renderer'webgl2'Which renderer to use. See Renderers.
labelEditablebooleantrueAllow double-click to open the inline label editor.
groupDoubleClickCollapsesbooleanfalseOpt-in: double-clicking a type: 'group' node toggles collapse.
readOnlybooleanfalseDisable every editing interaction.
backgroundstring'#f7f7f7'Canvas background color.
gridPartial<GridConfig>dots, 20pxGrid overlay config.
minimapPartial<MinimapConfig>Minimap overlay config. Omit to disable.
ariaLabelstring'Flowchart'Screen-reader label for the canvas.
historyLimitnumber100Max undo history entries.
snapGridnumber0Snap node drag to a grid of this size (world units). 0 disables.
autoFitbooleanfalseFit view to initial nodes after construct.
onError(err: Error) => voidCalled when the renderer cannot initialize.
onContextLost() => voidWebGL context lost (GPU reset, mobile tab backgrounded).
onContextRestored() => voidWebGL context restored after a loss event.
onBeforeConnect(params) => booleanReturn false to reject a connection before it is created.
onBeforeDelete(nodeIds, edgeIds) => booleanReturn false to cancel deletion.
sanitizeHtml(html: string) => stringSanitize NodeData.htmlContent before innerHTML. Required for untrusted input.

Node & edge mutation

MethodDescription
addNode(node) / removeNode(id) / updateNode(id, updates)Single-node operations. Each is one history entry.
addEdge(edge) / removeEdge(id) / updateEdge(id, updates)Single-edge operations.
setNodes(nodes) / setEdges(edges)Batch replace. One history entry.
getNode(id) / getEdge(id)Lookup by id.
getNodes() / getEdges()Returns a snapshot array (not live).
batchUpdate(fn)Run fn with batching: one history entry, one render flush at the end. Use for layout, import, bulk edits.

Selection

MethodDescription
getSelectedIds() / getSelectedEdgeIds()Currently selected ids.
setSelectedIds(ids)Replace selection.
clearSelection()Self-explanatory.

Viewport

MethodDescription
fitView(opts?)Frame all nodes with padding.
fitViewToSelection(opts?)Frame the current selection.
panTo(worldX, worldY)Move the canvas center to a world coordinate.
zoomIn() / zoomOut() / zoomTo(level)Discrete zoom (steps: 0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4).
scrollToNode(id, padding?)Pan so the node is visible.
getNodesBounds(ids?)AABB of given nodes (or all nodes).

History (undo / redo)

MethodDescription
undo() / redo()Self-explanatory. Emit historyChange.
canUndo() / canRedo()Booleans.
clearHistory()Wipe the undo stack. Emits historyChange.

Groups & layout

MethodDescription
groupNodes(parentId, childIds)Assign parentId to each child.
ungroupNodes(childIds)Strip parentId from each child. Group container survives.
dissolveGroup(groupId)Remove the group container + detach all its children. Single undo entry. Use this when the group node itself should disappear.
collapseNode(id) / expandNode(id) / toggleCollapse(id)Group-only. No-op on non-group nodes.
alignNodes(axis) / distributeNodes(axis)Selection-based alignment.
animateLayout(targets, duration)Smoothstep RAF interpolation to a target layout.

Styling

MethodDescription
setNodeShape(id, shape)'rectangle' | 'circle' | 'diamond' | 'hexagon'.
setEdgeStyle(id, style)Merge a partial style onto an edge.
setNodeStatus(id, status | null)'error' | 'warning' | 'success' | 'info' | null.
setTheme('light' | 'dark')Preset background + grid color.
setBackground(color)Override background color.

Search & highlight

MethodDescription
searchNodes(query)Case-insensitive label search. Updates highlightedNodeIds.
setHighlightedNodes(ids) / clearHighlights()Direct control.

Graph analysis

MethodDescription
getIncomers(id) / getOutgoers(id) / getConnectedNodes(id)Adjacency via O(degree) nodeEdgeIndex.
getEdgesForNode(id)O(1) lookup.
getEdgesBetween(sourceId, targetId)Both directions.
hasCycle()DFS 3-color.
findPaths(sourceId, targetId)DFS. Capped at 100 paths.

Import / export

MethodDescription
toJSON() / fromJSON(data)Serialization roundtrip. fromJSON validates the schema.
importJSON(data, mode='replace' | 'merge')Schema-validated import. Use mode: 'merge' to add to the existing graph.
exportPNG(scale?)Returns a data URL.
exportSVG(padding?)Returns an SVG string.

Lifecycle

MethodDescription
dispose()Tear down the WebGL context, remove overlays, detach every event listener. Always call this when the container is removed.

Events

ts
chart.on(eventName, handler)
chart.off(eventName, handler)
EventPayload
nodeClick{ node: NodeData }
nodeDoubleClick{ node: NodeData }
nodeDragStart{ id: string }
nodeDragEnd{ id, x, y }
nodeHover{ node: NodeData | null }
nodeAdd / nodeRemove / nodeUpdatemutation events
nodeResize{ id, x, y, width, height }
edgeClick / edgeDoubleClick / edgeHoveredge events
edgeAdd / edgeRemove / edgeUpdatemutation events
connect{ sourceId, targetId, sourceHandle, targetHandle }
paneClick{ x, y }
selectionChange{ selectedIds, edgeIds }
viewportChangeviewport state
historyChange{ canUndo, canRedo }

Types

ts
interface NodeData {
  id: string
  x: number
  y: number
  width: number
  height: number
  label: string
  type?: 'group'
  parentId?: string
  collapsed?: boolean
  locked?: boolean
  tooltip?: string
  ariaLabel?: string
  htmlContent?: string
  ports?: Port[]
  style?: NodeStyle
  status?: NodeStatus
}

interface EdgeData {
  id: string
  source: string
  target: string
  sourceHandle?: string
  targetHandle?: string
  label?: string
  animated?: boolean
  waypoints?: Array<{ x: number, y: number }>
  style?: EdgeStyle
}

Full type signatures are emitted to dist/index.d.ts — your editor will autocomplete the rest. If you find a public method without an entry on this page, please open an issue or a PR.


0.5.0 → 0.9.1 surface

Every API added between 0.5.0 and 0.9.1 — the cycles that closed the React-Flow-parity track, opened the reactive-data layer, hardened production, and shipped the first plugin contract.

Overlays (0.5.0 + 0.6.0 + 0.7.0)

DOM overlays mount inside the chart container. Each layer is constant pixel size under zoom except ViewportPortal, which scales with the viewport.

ts
// Panel — 9-position floating widget
chart.addPanel({ position: 'top-right', content: '<button>…</button>' }): string
chart.updatePanel(id, partial): boolean
chart.removePanel(id): boolean
chart.listPanels(): string[]

// Controls — zoom/fit/lock built-ins + custom buttons
chart.showControls({ position: 'bottom-left', showFitView: true }): void
chart.hideControls(): void
chart.hasControls(): boolean

// NodeToolbar — anchored to a node, visible iff selection matches
chart.addNodeToolbar({ nodeId: 'a', content: '🗑', position: 'top', align: 'center' }): string
chart.updateNodeToolbar(id, partial): boolean
chart.removeNodeToolbar(id): boolean
chart.listNodeToolbars(): string[]

// EdgeToolbar — edge-anchored variant of NodeToolbar
chart.addEdgeToolbar({ edgeId: 'e1', content: '🗑', align: 'above' }): string
chart.updateEdgeToolbar(id, partial): boolean
chart.removeEdgeToolbar(id): boolean
chart.listEdgeToolbars(): string[]

// ViewportPortal — world-coord DOM, scales with zoom
chart.addViewportPortal({ x: 80, y: 380, width: 200, height: 60, content: '<div>…</div>' }): string
chart.updateViewportPortal(id, partial): boolean
chart.removeViewportPortal(id): boolean
chart.listViewportPortals(): string[]

// EdgeLabel — HTML edge label at the rendered-path midpoint
chart.addEdgeLabel({ edgeId: 'e1', content: '<span>↗ flow</span>' }): string
chart.updateEdgeLabel(id, partial): boolean
chart.removeEdgeLabel(id): boolean
chart.listEdgeLabels(): string[]

// PerfOverlay — FPS / frame time / draw call / atlas miss stats (differentiator)
chart.showPerfOverlay({ position: 'top-right' }): void
chart.hidePerfOverlay(): void

Edge variants (0.7.0)

'smoothstep' joins 'bezier' / 'straight' / 'step'. Same sampled polyline on Canvas2D + WebGL2 (T5 parity).

ts
chart.addEdge({
  id: 'e1', source: 'a', target: 'b',
  type: 'smoothstep',
  pathOptions: { borderRadius: 16, arcSegments: 10 },
})

Node-level affordances (0.6.0 + 0.8.0)

ts
// extent — clamp child to its parent's bbox (or an explicit rect) on drag-end
chart.addNode({ id: 'c', parentId: 'g', extent: 'parent', /* … */ })
chart.addNode({ id: 'c', extent: { minX: 0, minY: 0, maxX: 800, maxY: 600 } })

// expandParent — drag the child out, parent grows to contain it
chart.addNode({ id: 'c', parentId: 'g', expandParent: true })

// easyConnect — inflated handle hit radius, connect from anywhere near the edge
chart.addNode({ id: 'a', easyConnect: true })

// NodeResize options — min/max bounds, aspect ratio, predicate, callbacks
chart.setNodeResizeOptions({
  minWidth: 50, minHeight: 40,
  maxWidth: 800, maxHeight: 600,
  keepAspectRatio: false,
  shouldResize: (node, next) => true,
  onResizeStart: (id) => {},
  onResize: (id, x, y, w, h) => {},
  onResizeEnd: (id, x, y, w, h) => {},
})
chart.getNodeResizeOptions(): NodeResizeOptions

Drag UX layers (0.8.0)

ts
// Helper Lines — Figma-style alignment guides + snap during drag
chart.setHelperLinesOptions({ enabled: true, snap: 5, show: 10 })
chart.getHelperLinesOptions(): HelperLinesOptions

// Proximity Connect — drag near another node → ghost line → drop creates edge
chart.setProximityConnectOptions({ enabled: true, threshold: 80 })
chart.getProximityConnectOptions(): ProximityConnectOptions

Computing Flows — reactive per-node data (0.8.0)

updateNodeData merges into node.data and fans out to subscribers. Explicit cycle detection — when a subscriber writes back to a node already on the active update stack, propagation stops and a nodeDataCycle event fires. Differentiator vs React Flow's equivalent, which stack-overflows on cycles.

ts
chart.updateNodeData(id: string, partial: Record<string, unknown>): boolean
chart.subscribeNodeData(id, (data, partial) => { /* … */ }): () => void
chart.getNodeDataSubscriberCount(id: string): number

// Events
chart.on('nodeDataChange', ({ id, data, partial }) => {})
chart.on('nodeDataCycle',  ({ id, chain }) => {})

Custom node-type registry (0.9.0) — plugin contract

Built-in shapes (rectangle, circle, diamond, hexagon) keep the WebGL2 SDF fast path. Plugins ship category: 'html' types that mount DOM overlays scaled with the viewport.

ts
chart.registerNodeType('uml-class', {
  category: 'html',
  defaultSize: { width: 200, height: 120 },
  render: (container, node, ctx) => {
    container.innerHTML = `<div class="uml-card">${node.label}</div>`
  },
  destroy: (container, node) => { /* optional teardown */ },
})

chart.addNode({ id: 'order', type: 'uml-class', label: 'Order', x: 0, y: 0, width: 200, height: 120 })

chart.unregisterNodeType(name: string): boolean
chart.getRegisteredNodeTypes(): string[]
chart.getCustomNodeTypes(): string[]

External plugins publish as @my-org/flowgl-node-*. See the Custom node-type plugins cookbook recipe for a complete walkthrough.

Theme (0.5.0)

ts
chart.setTheme('light' | 'dark' | 'system'): void   // 'system' tracks prefers-color-scheme live

React hooks (0.6.0) — @flowgl/react

tsx
import { FlowchartProvider, useFlowChart, useNodes, useEdges, useViewport, useSelection } from '@flowgl/react'

<FlowchartProvider value={chartRef.current}>
  <NodeList />     {/* useNodes() inside */}
</FlowchartProvider>

Subscribed to chart events via plain useState + useEffect — no new runtime dependency (Tenet T2 preserved).

Edge geometry helper (0.8.1) — also exported for plugin authors

ts
import { edgePathPoints, edgeMidpoint, edgeBoundingBox, edgePathFingerprint } from '@flowgl/core'

Layout helpers (0.9.1)

ts
import {
  hierarchicalLayout, forceLayout, gridLayout, circularLayout,
  addChildTranslations,
} from '@flowgl/core'

Every layout calls addChildTranslations before returning, so a layout that moves a group also relocates its descendants by the same delta. External layout plugins should do the same.


Type reference

Every public type exported from @flowgl/core. Importable directly:

ts
import type {
  // Core data
  NodeData, NodeStyle, NodeShape, NodeStatus, PortDef,
  EdgeData, EdgeStyle, EdgeType, EdgePathOptions,
  ViewportState, GridConfig, MinimapConfig, HandleSide,

  // Chart events
  FlowChartEvents,

  // NodeResize tuning
  NodeResizeOptions, NodeResizeRect,

  // Renderer plumbing — implement these to swap the renderer
  RendererOptions, RenderFrame,

  // Context menu API
  MenuItem, MenuEntry, MenuSeparator,

  // 0.5.0 — overlay options
  PanelPosition, PanelOptions,
  ControlsOptions, ControlButtonOptions,
  NodeToolbarSpec, NodeToolbarPosition, NodeToolbarAlign,
  PerfOverlayOptions,

  // 0.6.0
  ViewportPortalSpec,
  EdgeLabelSpec,

  // 0.7.0
  EdgeToolbarSpec, EdgeToolbarAlign,

  // 0.8.0
  HelperLinesOptions,
  ProximityConnectOptions,

  // 0.9.0 — node-type registry
  NodeTypeDefinition, NodeTypeCategory,
  HtmlNodeRenderFn, NodeHitTestFn,

  // Layouts
  LayoutResult, LayoutAlgorithm,
} from '@flowgl/core'

Defaults exposed as constants:

ts
import {
  DEFAULT_NODE_STYLE, DEFAULT_EDGE_STYLE,
  DEFAULT_GRID_CONFIG, DEFAULT_MINIMAP_CONFIG,
  MIN_ZOOM, MAX_ZOOM,
} from '@flowgl/core'

Stability tiers

Every symbol on this page is stable unless the docstring or SEMVER.md calls it out as @provisional. Stable APIs go through a deprecation cycle of at least two minor releases before removal.

Released under the MIT License.