TopologyBuilder
TopologyBuilder is the entry point for defining an architecture topology. It manages groups, standalone nodes, and edges, then commits everything to the React Flow store with a single apply() call.
const topology = new TopologyBuilder(autoLayout: boolean);| Parameter | Type | Description |
|---|---|---|
autoLayout | boolean | When true, node positions are computed automatically using a force-directed algorithm. When false, you must supply explicit x/y coordinates for every group. |
createGroup
Creates a group container and returns a GroupBuilder for adding nodes and sub-groups.
topology.createGroup(
id: string,
config: GroupConfig,
position?: { x: number; y: number }
): GroupBuilderGroupConfig
| Property | Type | Default | Description |
|---|---|---|---|
label | string | — | Display name shown in the group header |
width | number | 400 | Initial width in pixels (recalculated by autoResize) |
height | number | 200 | Initial height in pixels (recalculated by autoResize) |
style | object | {} | Inline CSS applied to the group container |
color | string | — | Border and header accent color (hex or CSS color) |
layer | string | — | Layer name; group is hidden when this layer is inactive |
Usage
const backendGroup = topology.createGroup('backend', {
label: 'Backend Services',
width: 700,
height: 300,
color: '#3b82f6',
layer: 'v2',
}, { x: 200, y: 300 });When autoLayout is true, the position argument is ignored. Pass it anyway for documentation purposes — it has no effect.
createProcess
Creates a standalone node (not inside any group) and adds it directly to the canvas.
topology.createProcess(config: ProcessConfig): TopologyBuilderProcessConfig
| 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 |
shape | string | 'default' | Node shape. See Node Types & Shapes |
layer | string | — | Layer name for visibility toggling |
replicas | number | — | Shorthand: creates N nodes with IDs id-1 … id-N |
shardId | string | — | Shard identifier shown as a badge |
shardRole | 'primary' | 'replica' | 'arbiter' | — | Shard role badge |
external | boolean | false | Marks the node as external (orange border styling) |
Usage
topology.createProcess({
id: 'cdn',
label: 'CDN',
shape: 'cloud',
external: true,
state: 'running',
});connect
Creates a directed edge between two nodes.
topology.connect(
source: string,
target: string,
options?: ConnectionOptions
): TopologyBuilderconnect(A, B) means A opens the TCP connection to B. The arrow direction represents who dials whom, not who sends data. Responses always travel back along the same edge in reverse — never create a duplicate edge for responses.
ConnectionOptions
| Property | Type | Default | Description |
|---|---|---|---|
label | string | — | Text shown on the edge midpoint |
protocol | string | — | Connection protocol. Controls edge color. See Edges & Protocols |
type | 'floating' | 'animated' | 'pulse' | 'floating' | Edge component to render |
layer | string | — | Layer name for visibility toggling |
animated | boolean | true | Whether the edge animates (dashes move) |
bidirectional | boolean | false | Renders arrows on both ends |
Usage
topology.connect('api', 'pg', {
protocol: 'postgresql',
label: 'SQL queries',
type: 'floating',
});
topology.connect('flink', 'kafka', {
protocol: 'kafka',
label: 'consume',
type: 'pulse',
});apply
Commits all groups, nodes, and edges to the Zustand store. Triggers a React re-render and populates the canvas.
await topology.apply(): Promise<void>apply() is asynchronous because it waits for React Flow to finish its layout pass before resolving. Always await it.
await topology.apply();
// Canvas is populated here. Safe to create FlowBuilder.
const flow = new FlowBuilder();autoResizeGroups
Recalculates the dimensions of all groups to fit their contents. Equivalent to calling .autoResize() on every GroupBuilder after the fact.
topology.autoResizeGroups(): TopologyBuilderUseful when you add nodes to groups dynamically and want a single resize pass at the end.
// Build all groups and nodes...
topology.autoResizeGroups();
await topology.apply();newRow
Signals the auto-layout engine to place the next group on a new row, below the current row of groups.
topology.newRow(): TopologyBuildertopology.createGroup('row1-left', { label: 'Service A' });
topology.createGroup('row1-right', { label: 'Service B' });
topology.newRow();
topology.createGroup('row2', { label: 'Database Layer' });Full example
const topology = new TopologyBuilder(true);
// External client (no group)
topology.createProcess({
id: 'internet',
label: 'Internet',
shape: 'cloud',
external: true,
});
// Frontend group
const frontendGroup = topology.createGroup('frontend', {
label: 'Frontend',
color: '#10b981',
});
frontendGroup
.addProcess({ id: 'nginx', label: 'Nginx', state: 'running' })
.addProcess({ id: 'spa', label: 'React SPA', state: 'running' })
.autoResize();
topology.newRow();
// Backend group
const backendGroup = topology.createGroup('backend', {
label: 'Backend',
color: '#3b82f6',
});
backendGroup
.addProcess({ id: 'api-1', label: 'API Pod 1', state: 'running' })
.addProcess({ id: 'api-2', label: 'API Pod 2', state: 'running' })
.addProcess({ id: 'pg', label: 'PostgreSQL', shape: 'cylinder', state: 'running' })
.autoResize();
// Connections
topology.connect('internet', 'nginx', { protocol: 'http', label: 'HTTPS' });
topology.connect('nginx', 'spa', { protocol: 'http', label: 'static' });
topology.connect('nginx', 'api-1', { protocol: 'http', label: 'proxy' });
topology.connect('nginx', 'api-2', { protocol: 'http', label: 'proxy' });
topology.connect('api-1', 'pg', { protocol: 'postgresql', label: 'SQL' });
topology.connect('api-2', 'pg', { protocol: 'postgresql', label: 'SQL' });
await topology.apply();
return null;