React Flow adapter for building visual flow editors with Runtype
npm install @runtypelabs/react-flowA React Flow adapter for building visual flow editors with Runtype. This package provides pre-built node components and hooks for creating, editing, and saving flows using the Runtype API.
> Official React Flow adapter published on npm
From the monorepo root, run:
``bash`
pnpm dev:react-flow-example
This will build the package and start the example app at http://localhost:3100
`bash`
pnpm add @runtypelabs/react-flow @xyflow/react
`tsx
import { RuntypeFlowEditor } from '@runtypelabs/react-flow'
import { createClient } from '@runtypelabs/sdk'
import '@xyflow/react/dist/style.css'
const client = createClient({
apiKey: 'your-api-key',
})
function MyFlowEditor() {
return (
Features
- Pre-built Node Components: Ready-to-use nodes for prompt, fetch URL, code, conditional, and send email steps
- API Integration: Seamlessly load, save, and create flows using
@runtypelabs/sdk
- Validation: Built-in validation for all step types
- Auto-layout: Automatic node positioning
- Fully Typed: Complete TypeScript supportSupported Step Types
| Step Type | Node Component | Description |
| ---------------- | --------------- | --------------------------------------- |
|
prompt | PromptNode | AI text generation with model selection |
| fetch-url | FetchUrlNode | HTTP requests to fetch data |
| transform-data | CodeNode | JavaScript code execution |
| conditional | ConditionalNode | Branch execution based on conditions |
| send-email | SendEmailNode | Send emails |Components
$3
The main editor component that wraps React Flow with Runtype integration.
`tsx
client={runtypeClient}
flowId="optional-existing-flow-id"
initialName="My Flow"
initialDescription="A description"
initialSteps={[]}
onSave={(flow) => {...}}
onChange={(nodes, edges) => {...}}
onStepSelect={(step) => {...}}
showToolbar={true}
readOnly={false}
className="my-editor"
/>
`Props:
| Prop | Type | Description |
| -------------------- | ------------------------ | ------------------------------------------------ |
|
client | RuntypeClient | Required. Runtype API client instance |
| flowId | string | ID of an existing flow to load |
| initialName | string | Initial flow name for new flows |
| initialDescription | string | Initial flow description |
| initialSteps | FlowStep[] | Initial steps to populate |
| onSave | (flow) => void | Callback when flow is saved |
| onChange | (nodes, edges) => void | Callback when flow changes |
| onStepSelect | (step) => void | Callback when a step is selected |
| showToolbar | boolean | Whether to show the toolbar (default: true) |
| readOnly | boolean | Whether the editor is read-only (default: false) |
| className | string | Custom class name for the container |Hooks
$3
Manages flow state and API operations.
`tsx
import { useRuntypeFlow } from '@runtypelabs/react-flow'function MyCustomEditor() {
const {
nodes,
edges,
onNodesChange,
onEdgesChange,
onConnect,
flowName,
setFlowName,
loadFlow,
saveFlow,
createFlow,
addStep,
deleteStep,
updateStep,
isLoading,
isSaving,
error,
hasUnsavedChanges,
} = useRuntypeFlow({
client,
flowId: 'optional-flow-id',
})
// Use with ReactFlow
return (
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
/>
)
}
`$3
Validates flow steps and returns errors/warnings.
`tsx
import { useFlowValidation } from '@runtypelabs/react-flow'function ValidationStatus({ nodes }) {
const { result, getStepErrors, getStepWarnings } = useFlowValidation({ nodes })
return (
Valid: {result.isValid ? 'Yes' : 'No'}
Errors: {result.errors.length}
Warnings: {result.warnings.length}
)
}
`Utilities
$3
Convert between Runtype flow steps and React Flow nodes:
`tsx
import {
flowStepsToNodes,
nodesToFlowSteps,
createEdgesFromNodes,
createDefaultStep,
} from '@runtypelabs/react-flow'// Convert Runtype steps to React Flow nodes
const nodes = flowStepsToNodes(steps, {
onChange: (stepId, updates) => {...},
onDelete: (stepId) => {...},
})
// Convert back to Runtype steps
const steps = nodesToFlowSteps(nodes)
// Create edges between nodes
const edges = createEdgesFromNodes(nodes)
// Create a new default step
const newStep = createDefaultStep('prompt', 0)
`$3
Auto-layout nodes for better visualization:
`tsx
import { autoLayout, centerNodes, snapToGrid } from '@runtypelabs/react-flow'// Auto-layout nodes based on edges
const layoutedNodes = autoLayout(nodes, edges, {
direction: 'vertical',
startPosition: { x: 400, y: 50 },
})
// Center nodes in viewport
const centeredNodes = centerNodes(nodes, viewportWidth, viewportHeight)
// Snap nodes to grid
const snappedNodes = snapToGrid(nodes, 20)
`Custom Node Components
You can use individual node components directly:
`tsx
import {
PromptNode,
FetchUrlNode,
CodeNode,
ConditionalNode,
SendEmailNode,
BaseNode,
} from '@runtypelabs/react-flow'// Register with ReactFlow
const nodeTypes = {
prompt: PromptNode,
'fetch-url': FetchUrlNode,
'transform-data': CodeNode,
conditional: ConditionalNode,
'send-email': SendEmailNode,
}
`TypeScript
Full TypeScript support with exported types:
`tsx
import type {
FlowStep,
RuntypeNode,
RuntypeEdge,
RuntypeNodeData,
PromptStepConfig,
FetchUrlStepConfig,
TransformDataStepConfig,
ConditionalStepConfig,
SendEmailStepConfig,
FlowValidationResult,
ValidationError,
ValidationWarning,
SavedFlow,
} from '@runtypelabs/react-flow'
`Development Notes
$3
This package exports TypeScript types directly from source files to ensure compatibility across different React versions. TypeScript users will get full type inference automatically.
$3
This package requires the following peer dependencies:
-
react ^18.0.0
- react-dom ^18.0.0
- @xyflow/react ^12.0.0$3
Import React Flow's styles in your application:
`tsx
import '@xyflow/react/dist/style.css'
``MIT