Give ideas
a structure.
Build interactive graphs with nodes, edges, ports and connections. Shape the experience through composable renderers, policies and themes.
Try ComposeThe graph and system modelling toolkit
Foldkit Zloz is a functional, extensible graph toolkit for interactive node editors, C4 architecture modelling, and Mermaid export.
Compose. Connect. Communicate.
Build interactive graphs with nodes, edges, ports and connections. Shape the experience through composable renderers, policies and themes.
Try ComposeDescribe people, software systems and containers with built-in C4 semantics. Keep architectural meaning in the model, independent of its visual form.
Download this C4 modelExport Mermaid for documentation and collaboration. Review conversion losses and preserve identity metadata alongside the diagram source.
Inspect the Mermaid exportCompose / Live Foldkit example
Select a node, connect Review to Publish, and undo the change. The same package owns the graph, input handling and history.
This example resets on reload. Explore the full workbench ↗
import {
createEditor,
updateEditor,
type EditorEvent,
type EditorState,
type ZlozGraph,
} from '@opsydyn/foldkit-zloz';
import { Schema } from 'effect';
import { defineMessageUnion } from 'foldkit/message';
import type { Return } from 'foldkit/update';
const input = { id: 'in', label: 'Input', kind: 'input', side: 'top', offset: 0.5 } as const;
const output = { id: 'out', label: 'Output', kind: 'output', side: 'bottom', offset: 0.5 } as const;
/** Vertical workflow keeps node text legible at both desktop and narrow widths. */
const initialGraph: ZlozGraph = {
nodes: [
{
id: 'draft',
label: 'Draft',
position: { x: 80, y: 30 },
size: { width: 220, height: 80 },
ports: [output],
},
{
id: 'review',
label: 'Review',
position: { x: 80, y: 180 },
size: { width: 220, height: 80 },
ports: [input, output],
},
{
id: 'publish',
label: 'Publish',
position: { x: 80, y: 330 },
size: { width: 220, height: 80 },
ports: [input],
},
],
edges: [
{
id: 'draft-review',
source: { node: 'draft', port: 'out' },
target: { node: 'review', port: 'in' },
pathStyle: 'smooth',
},
],
};
// Opaque package state is constructed only by createEditor/updateEditor, never decoded from props.
export const Model = Schema.Struct({ editor: Schema.Unknown });
export type Model = Readonly<{ editor: EditorState }>;
export const Message = defineMessageUnion({ ObservedZlozInput: { event: Schema.Unknown } });
export type Message = typeof Message.Type;
export const observe = (event: EditorEvent): Message => Message.ObservedZlozInput({ event });
export const init = (): Return<Model, Message> => ({
model: {
editor: createEditor(initialGraph, {
fitViewPadding: 24,
zoomLimits: { minZoom: 0.2, maxZoom: 1.25 },
}),
},
});
export const update = (model: Model, message: Message): Return<Model, Message> =>
Message.match(message, {
ObservedZlozInput: ({ event: raw }) => {
// SAFETY: zlozView and the controls below emit the public, typed EditorEvent contract.
const event = raw as EditorEvent;
const next = updateEditor(model.editor, event);
const editor =
event.type === 'SurfaceMeasured' && model.editor.surface === null
? updateEditor(next, { type: 'FitViewClicked' })
: next;
return { model: { ...model, editor } };
},
});
Open by nature
This is the actual export of the context model above. Mermaid is a projection: canonical JSON retains the full editable model.
Download source, identity and loss reportflowchart LR
n_63_75_73_74_6f_6d_65_72("Customer")
n_6f_72_64_65_72_73["Order platform"]
n_70_61_79_6d_65_6e_74_73["Payments"]
n_64_65_6c_69_76_65_72_79["Delivery"]
n_63_75_73_74_6f_6d_65_72 e_70_6c_61_63_65_73_2d_6f_72_64_65_72@-->|"Places order"| n_6f_72_64_65_72_73
n_6f_72_64_65_72_73 e_63_68_61_72_67_65_73@-->|"Charges"| n_70_61_79_6d_65_6e_74_73
n_6f_72_64_65_72_73 e_64_69_73_70_61_74_63_68_65_73@-->|"Dispatches"| n_64_65_6c_69_76_65_72_79
Pure functions, composition and immutable data. State and changes stay explicit.
Separate the graph model from its visual form. Use the core on its own.
Build your own nodes, edges, layouts and tools through public contracts.
Models should travel beyond the editor, not be trapped inside it.
A Foldkit family member
Zloz comes from Złóż: fold, assemble, put together. What began as a node-and-edge editor has grown into a toolkit for composing, exploring and communicating complex systems.
Foldkit is the UI toolkit. Zloz is its graph and system modelling toolkit.
Start with the model