API ReferenceGroupBuilder

GroupBuilder

GroupBuilder is the fluent interface returned by topology.createGroup(...). It provides methods for adding nodes, controlling layout, and nesting sub-groups.

You never instantiate GroupBuilder directly — you always get one from createGroup.

const group = topology.createGroup('my-group', { label: 'My Group' });
// group is a GroupBuilder instance

All methods return this (the same GroupBuilder), enabling method chaining.


addProcess

Adds a node to the group.

group.addProcess(config: ProcessConfig): GroupBuilder

ProcessConfig

PropertyTypeDefaultDescription
idstringRequired. Unique node identifier across the entire topology
labelstringRequired. Display name
state'running' | 'stopped' | 'error' | 'warning''running'Visual state indicator dot
iconstringPictogram inside the node. See Node Types & Shapes for the full list
shapestring'default'Node shape. See Node Types & Shapes
layerstringLayer name for visibility toggling
replicasnumberCreates N nodes with IDs id-1id-N automatically
shardIdstringShard identifier badge (e.g. 'shard-0')
shardRole'primary' | 'replica' | 'arbiter'Shard role badge
externalbooleanfalseOrange border styling for external dependencies

Usage

group
  .addProcess({ id: 'api',   label: 'API Server',  state: 'running' })
  .addProcess({ id: 'cache', label: 'Redis',        shape: 'cylinder', state: 'running' })
  .addProcess({ id: 'db',    label: 'PostgreSQL',   shape: 'cylinder', state: 'running' });

Replica shorthand

Instead of calling addProcess three times for three identical pods:

// Long form
group
  .addProcess({ id: 'api-1', label: 'API Pod 1', state: 'running' })
  .addProcess({ id: 'api-2', label: 'API Pod 2', state: 'running' })
  .addProcess({ id: 'api-3', label: 'API Pod 3', state: 'running' });
 
// Shorthand — equivalent result
group.addProcess({ id: 'api', label: 'API Pod', state: 'running', replicas: 3 });

The shorthand creates nodes with IDs api-1, api-2, api-3 automatically.


newRow

Inserts a row break in the group’s grid layout. Subsequent nodes are placed on the next row.

group.newRow(): GroupBuilder

By default, nodes are placed left-to-right in a single row. Call newRow() to start a new row:

group
  .addProcess({ id: 'master', label: 'Master', state: 'running' })
  .newRow()
  .addProcess({ id: 'slave-1', label: 'Slave 1', state: 'running' })
  .addProcess({ id: 'slave-2', label: 'Slave 2', state: 'running' })
  .autoResize();

autoResize

Recalculates the group’s width and height to fit all nodes with proper padding.

group.autoResize(): GroupBuilder
⚠️

Always call autoResize() after adding all nodes to a group. Without it, the group rectangle may be too small and nodes will overflow or overlap visually.

group
  .addProcess({ id: 'a', label: 'Service A' })
  .addProcess({ id: 'b', label: 'Service B' })
  .addProcess({ id: 'c', label: 'Service C' })
  .autoResize(); // must be last

addGroup

Creates a nested sub-group inside the current group and returns the child GroupBuilder so you can add nodes to it.

const child = parentGroup.addGroup(config: { id: string; label: string }): GroupBuilder
⚠️

Always use parentGroup.addGroup() to create nested groups. Do NOT use topology.createGroup('child', { parentId: 'parent' }) — the parentId option is not supported on createGroup and the child will not be nested.

Basic nesting

const cluster = topology.createGroup('cluster', { label: 'Cluster', x: 80, y: 40 });
 
const shard0 = cluster.addGroup({ id: 'shard-0', label: 'Shard 0' });
shard0
  .addProcess({ id: 'primary', label: 'Primary', icon: 'database', shardRole: 'primary', state: 'running' })
  .addProcess({ id: 'replica', label: 'Replica', icon: 'database', shardRole: 'replica', state: 'running' })
  .autoResize();
 
const shard1 = cluster.addGroup({ id: 'shard-1', label: 'Shard 1' });
shard1
  .addProcess({ id: 'primary-1', label: 'Primary', icon: 'database', shardRole: 'primary', state: 'running' })
  .addProcess({ id: 'replica-1', label: 'Replica', icon: 'database', shardRole: 'replica', state: 'running' })
  .autoResize();
 
// IMPORTANT: autoResize() bottom-up — children first, then parent
cluster.autoResize();

How it works

  • addGroup() internally calls topology.addToGroup(childId, parentId), which sets parentId and extent: 'parent' on the child node
  • React Flow 12 visually nests the child inside the parent
  • Child positions are relative to the parent group
  • Supported parent container types: GROUP, CONTAINER, HOST, VM, DATACENTER, CLOUD
  • Arbitrary nesting depth is supported (e.g. Cloud > Region > VPC > Subnet > Service)

addCloud

Adds a cloud-shape external service placeholder inside the group.

group.addCloud(config: ProcessConfig): GroupBuilder

Equivalent to addProcess({ ...config, shape: 'cloud', external: true }) — a convenience shorthand for representing external cloud services.

group.addCloud({ id: 's3', label: 'Amazon S3', state: 'running' });

skip

Inserts an empty cell in the grid layout — equivalent to a spacer. Useful for aligning nodes in a grid when some positions should be empty.

group.skip(): GroupBuilder
group
  .addProcess({ id: 'a', label: 'Node A' })
  .skip()                                    // empty cell
  .addProcess({ id: 'b', label: 'Node B' }) // placed in column 3
  .autoResize();

Chaining example

chaining-example.ts
const topology = new TopologyBuilder(true);
 
topology.createGroup('kafka-cluster', {
  label: 'Kafka Cluster',
  color: '#f59e0b',
})
  .addProcess({ id: 'broker-1', label: 'Broker 1', state: 'running', shardId: 'p0', shardRole: 'primary' })
  .addProcess({ id: 'broker-2', label: 'Broker 2', state: 'running', shardId: 'p0', shardRole: 'replica' })
  .addProcess({ id: 'broker-3', label: 'Broker 3', state: 'running', shardId: 'p1', shardRole: 'primary' })
  .newRow()
  .addProcess({ id: 'zk-1', label: 'ZooKeeper 1', state: 'running' })
  .addProcess({ id: 'zk-2', label: 'ZooKeeper 2', state: 'running' })
  .addProcess({ id: 'zk-3', label: 'ZooKeeper 3', state: 'running' })
  .autoResize();
 
await topology.apply();
return null;