openbrain
Concepts

Nodes & Edges

The building blocks of flow workflows.

Nodes & Edges

Workflows in flow are directed acyclic graphs (DAGs) made up of nodes and edges. Nodes perform operations — generating images, transforming text, routing data — and edges carry typed values between them.

Node categories

CategoryPurposeExamples
VariablesProvide input values to the workflowText, Image, Number, Boolean, JSON
GeneratorsCreate new content using AI modelsFlux Schnell, Stable Diffusion, Kling, Minimax
LogicControl data flowRouter, Filter, Conditional
ComposeCombine multiple inputsImage Composite, Video Stitch, Concat
TransformModify existing contentUpscale, Background Remove, Face Swap, Style Transfer
ActionProduce side effectsHTTP Request, Webhook
UtilityHelper operationsPreview, JavaScript, Prompt Template, List

Node data structure

Every node has the same base structure:

interface NodeData {
  defType: string;       // Plugin type identifier (e.g. "fal-flux-schnell")
  label: string;         // Display name
  config: Record<string, unknown>;  // Plugin-specific configuration
  handleCounts: Record<string, number>;  // Dynamic handle counts
}
  • defType links the node to its plugin definition (NodeDef), which declares the available handles, config fields, and step function.
  • config stores user-configured values like model parameters, prompt text, or image dimensions. Each plugin defines which config fields are available.
  • handleCounts tracks the count for expandable handles. For example, an image composite node might have { "layer": 3 } to indicate three layer inputs.

Edges

Edges connect an output handle on one node to an input handle on another:

interface Edge {
  id: string;
  source: string;       // Source node ID
  sourceHandle: string;  // Output handle ID on the source
  target: string;       // Target node ID
  targetHandle: string;  // Input handle ID on the target
}

Connections are type-checked — you can only connect an output to an input with a compatible handle type. The editor enforces this visually and prevents invalid connections.

Data flow

Data flows left to right through the graph:

[Text Variable] ──TEXT──> [Flux Schnell] ──IMAGE──> [Upscale] ──IMAGE──> [Preview]
     "a cat"                  prompt          image           image
  1. Variable nodes produce their configured values as outputs (e.g. a text node outputs its text content)
  2. The execution engine resolves edges to determine which values flow into each node's inputs
  3. Each node executes with its resolved inputs and produces outputs
  4. Outputs flow along edges to downstream nodes
  5. The process continues in topological order until all nodes have executed

Nodes with no input edges (like variable nodes) execute first. Nodes with multiple inputs wait until all upstream nodes have completed.

Node identity

All entity IDs in flow use nanoid-based identifiers with prefixes:

EntityPrefixExample
Projectpj-pj-abc123def456
Workflowwf-wf-xyz789ghi012
Workflow Runwr-wr-run456jkl789
Node Runnr-nr-nod012mno345

IDs are 12 lowercase alphanumeric characters after the prefix, generated via lib/nanoid.ts.

Durable vs. ephemeral data

Node data exists in two forms:

Field prefixStorageLifecycle
No prefix (config, label, handleCounts)Yjs document (durable, synced)Persisted across sessions, synced between users
_ prefix (_output, _inputs, _runs)React state (ephemeral)Per-client, recomputed on load, stripped before persistence
selected, measured, draggingReact state (ephemeral)React Flow internal state, never persisted

The toDurable() function strips all ephemeral fields before writing to Yjs, ensuring only stable configuration is synced and persisted.

On this page