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 instanceAll methods return this (the same GroupBuilder), enabling method chaining.
addProcess
Adds a node to the group.
group.addProcess(config: ProcessConfig): GroupBuilderProcessConfig
| Property | Type | Default | Description |
|---|---|---|---|
id | string | — | Required. Unique node identifier across the entire topology |
label | string | — | Required. Display name |
state | 'running' | 'stopped' | 'error' | 'warning' | 'running' | Visual state indicator dot |
icon | string | — | Pictogram inside the node. See Node Types & Shapes for the full list |
shape | string | 'default' | Node shape. See Node Types & Shapes |
layer | string | — | Layer name for visibility toggling |
replicas | number | — | Creates N nodes with IDs id-1 … id-N automatically |
shardId | string | — | Shard identifier badge (e.g. 'shard-0') |
shardRole | 'primary' | 'replica' | 'arbiter' | — | Shard role badge |
external | boolean | false | Orange 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(): GroupBuilderBy 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(): GroupBuilderAlways 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 lastaddGroup
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 }): GroupBuilderAlways 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 callstopology.addToGroup(childId, parentId), which setsparentIdandextent: '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): GroupBuilderEquivalent 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(): GroupBuildergroup
.addProcess({ id: 'a', label: 'Node A' })
.skip() // empty cell
.addProcess({ id: 'b', label: 'Node B' }) // placed in column 3
.autoResize();Chaining example
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;