Solid Flow is a port of React Flow and Svelte Flow for SolidJS.
☣️ Solid Flow is alpha and currently under development. The API intends to follow React/Svelte Flow closely but some things might change for the sake of SolidJS. ☣️
The easiest way to get the latest version of Solid Flow is to install it via npm, yarn or pnpm:
npm install @dschz/solid-flow
pnpm install @dschz/solid-flow
yarn install @dschz/solid-flow
bun install @dschz/solid-flow
This is a basic example to get you started. For more advanced examples and full API documentation, explore the playground examples included in this repository.
import {
SolidFlow,
SolidFlowProvider,
Controls,
Background,
MiniMap,
addEdge,
type EdgeConnection,
createEdgeStore,
createNodeStore,
type Viewport,
} from "@dschz/solid-flow";
import "@dschz/solid-flow/styles"; // Required styles
import { createStore, produce } from "solid-js/store";
export default function Page() {
return (
<SolidFlowProvider>
<Flow />
</SolidFlowProvider>
)
}
function Flow() {
// Can invoke useSolidFlow due to parent Page + SolidFlowProvider wrapper. Contains all helper APIs
const { .. } = useSolidFlow();
// Use createNodeStore and createEdgeStore for reactive state management
const [nodes, setNodes] = createNodeStore([
{
id: "1",
type: "input",
data: { label: "Input Node" },
position: { x: 250, y: 0 },
},
{
id: "2",
type: "default",
data: { label: "Default Node" },
position: { x: 100, y: 100 },
},
{
id: "3",
type: "output",
data: { label: "Output Node" },
position: { x: 250, y: 200 },
},
]);
const [edges, setEdges] = createEdgeStore([
{ id: "e1-2", source: "1", target: "2" },
{ id: "e2-3", source: "2", target: "3" },
]);
const [viewport, setViewport] = createStore<Viewport>({
x: 100,
y: 100,
zoom: 5,
});
const updateViewport = () => {
setViewport("x", (prev) => prev + 10);
};
const onConnect = (connection: EdgeConnection) => {
/**
* Solid Flow updates the node/edge stores internally. The user-land edge store will have the connection inserted by the time onConnect fires so we can just go ahead and update the state of it
*/
setEdges(
(edge) => edge.id === connection.id,
produce((edge) => {
edge.animated = true;
}),
);
};
return (
<SolidFlow nodes={nodes} edges={edges} onConnect={onConnect} fitView>
<Controls />
<MiniMap />
<Panel position="top-left">
<button onClick={updateViewport}>Update viewport</button>
</Panel>
<Background variant="dots" />
</SolidFlow>
);
}
// Main flow instance with full API
const solidFlow = useSolidFlow();
// Reactive access to nodes and edges
const nodes = useNodes();
const edges = useEdges();
// Viewport control and monitoring
const viewport = useViewport();
// Connection state during drag operations
const connection = useConnection();
// Reactive access to node data
const nodeData = useNodesData(["node-1", "node-2"]);
// Node connection information
const connections = useNodeConnections("node-1");
// Create reactive stores (replaces signals)
const [nodes, setNodes] = createNodeStore(initialNodes);
const [edges, setEdges] = createEdgeStore(initialEdges);
// Update stores with SolidJS patterns
import { produce } from "solid-js/store";
setNodes(
(node) => node.id === "1",
produce((node) => {
node.position.x += 20;
}),
);
// Add new connections
setEdges(addEdge(connection, edges));
// Coordinate transformations (via useSolidFlow)
const { screenToFlowPosition, flowToScreenPosition } = useSolidFlow();
// Node/edge utilities
getNodesBounds(nodes);
getIntersectingNodes(node, nodes);
Create fully customized components with multiple handles:
import { Handle, type NodeProps } from "@dschz/solid-flow";
// Type-safe custom node component
function CustomNode(props: NodeProps<{ label: string }, "custom">) {
return (
<div class="custom-node" style={{ padding: "10px", background: "white" }}>
<Handle type="target" position="top />
<div>{props.data.label}</div>
<Handle type="source" position="bottom" id="output-a" />
<Handle type="source" position="bottom id="output-b" style={{ left: "80%" }} />
</div>
);
}
// Create type-safe node types
const nodeTypes = {
custom: CustomNode,
} satisfies NodeTypes;
// Use with typed store
const [nodes] = createNodeStore<typeof nodeTypes>([...]);
<SolidFlow nodeTypes={nodeTypes} nodes={nodes} ... />
import { type Connection } from "@dschz/solid-flow";
const isValidConnection = (connection: Connection) => {
// Custom validation logic
return connection.source !== connection.target;
};
const onConnect = (connection: Connection) => {
console.log("New connection:", connection);
setEdges(addEdge(connection, edges));
};
<SolidFlow
isValidConnection={isValidConnection}
onConnect={onConnect}
...
/>
<SolidFlow
onNodeClick={(event, node) => console.log("Node clicked:", node)}
onNodeDrag={(event, node) => console.log("Node dragged:", node)}
onEdgeClick={(event, edge) => console.log("Edge clicked:", edge)}
onPaneClick={(event) => console.log("Pane clicked")}
onSelectionChange={(params) => console.log("Selection changed:", params)}
/>
Solid Flow includes comprehensive accessibility features:
The repository includes a comprehensive playground with 25+ examples:
Run the examples locally:
bun start
Some pre-requisites before install dependencies:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
curl -fsSL https://bun.sh/install | bash
nvm use
bun install
bun start
bun run lint # checks source for lint violations
bun run format # checks source for format violations
bun run lint:fix # fixes lint violations
bun run format:fix # fixes format violations
The only requirements when contributing are:
main
instead of making merge commits.main