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. ☣️
- onlyRenderVisibleElements: render only visible elements.
- Custom MiniMap Nodes: define custom minimap jsx node elements.
- Edge Reconnect Anchors: the ability to re-connect already connected edges.
- Easy to use: Seamless zooming and panning, single- and multi selection of graph elements and keyboard shortcuts are supported out of the box
- Customizable: Different node types (Input, Output, Default, Group) and edge types (Bezier, Straight, Step, SmoothStep) with full support for custom nodes and edges
- Fast rendering: Only nodes that have changed are re-rendered using SolidJS's fine-grained reactivity
- Rich Plugin Ecosystem: Background patterns, Interactive MiniMap, Zoom Controls, Node Toolbar, and Node Resizer components
- Powerful Hooks: Comprehensive set of reactive hooks for nodes, edges, viewport, connections, and data management
- Full Accessibility: Complete keyboard navigation, screen reader support, ARIA labels, and focus management
- Drag & Drop: Built-in dragging for nodes, external drag-and-drop support, and customizable drag handles
- Advanced Features: Node grouping, intersection detection, connection validation, and subflow support
- TypeScript First: Fully typed API with generic type support and IntelliSense integration
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-flowThis 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>
  );
}- InputNode - Nodes with source handles only (starting points)
- OutputNode - Nodes with target handles only (ending points)
- DefaultNode - Standard nodes with both source and target handles
- GroupNode - Container nodes for organizing other nodes
- BezierEdge - Smooth curved connections (default)
- StraightEdge - Direct straight line connections
- StepEdge - Right-angle step connections
- SmoothStepEdge - Rounded step connections
- Background - Customizable canvas backgrounds (dots, lines, cross patterns)
- Controls - Zoom in/out, fit view, lock/unlock interactions
- MiniMap - Interactive overview with viewport indicator
- NodeToolbar - Context-sensitive toolbars for nodes
- NodeResizer - Real-time node resizing with handles
// 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:
- Full keyboard navigation support
- Screen reader compatibility with ARIA labels
- Focus management and visual indicators
- High contrast and color mode support
- Customizable keyboard shortcuts
- Reactive Updates: Only re-renders components when their specific data changes
- Viewport Optimization: Option to render only visible elements (coming soon)
- Memory Efficient: Optimized data structures for large graphs
- Stress Tested: Handles hundreds of nodes smoothly
The repository includes a comprehensive playground with 25+ examples:
- Basic Usage - Simple flows and interactions
- Custom Nodes - Creating specialized node types
- Edge Types - Different connection styles
- Drag & Drop - External elements and node creation
- Validation - Connection rules and constraints
- Subflows - Hierarchical node organization
- Performance - Large dataset handling
- Accessibility - Keyboard navigation and screen readers
Run the examples locally:
bun startSome pre-requisites before install dependencies:
- Install Node Version Manager (NVM)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
- Install Bun
curl -fsSL https://bun.sh/install | bash
nvm use
bun installbun startbun 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 violationsThe only requirements when contributing are:
- You keep a clean git history in your branch
- rebasing maininstead of making merge commits.
 
- rebasing 
- Using proper commit message formats that adhere to conventional commits
- Additionally, squashing (via rebase) commits that are not conventional commits
 
- CI checks pass before merging into main