A React-based workflow editor compatible with n8n, built using ReactFlow and modern React patterns.
- โ n8n Compatible: Uses n8n's workflow format and can integrate with n8n's node ecosystem
- โ React Context Architecture: Hierarchical state management mirroring n8n's design patterns
- โ ReactFlow Integration: Modern canvas with zoom, pan, minimap, and controls
- โ Dynamic Parameter Forms: Auto-generated forms using react-hook-form + zod validation
- โ TypeScript Support: Full type safety with n8n interfaces
- โ Tailwind CSS: Utility-first styling with responsive design
- โ Sample Nodes: Manual Trigger and Set nodes for demonstration
WorkflowProvider # Main workflow state and n8n data management
โ
ReactFlowProvider # ReactFlow functionality
โ
NodeProvider # Individual node state and operations
โ
UI Components # Parameter panels, node components, etc.
- WorkflowCanvas: Main ReactFlow canvas with n8n node integration
- N8nNode: Custom ReactFlow node component that renders n8n nodes
- ParameterPanel: Dynamic form panel for node configuration
- NodeProvider: Individual node state management (critical for n8n compatibility)
- n8n workflow format โ ReactFlow format conversion
- Real-time parameter updates with debouncing
- Event-driven architecture with React callback patterns
- Node.js >= 18.0.0
- pnpm >= 8.0.0 (or npm/yarn)
# Clone the repository
git clone https://github.com/koolii/react-workflow-editor.git
cd react-workflow-editor
# Install dependencies
pnpm install
# Start development server
pnpm dev
pnpm build
pnpm typecheck
pnpm lint
pnpm lint:fix
The application includes a sample workflow with Manual Trigger and Set nodes. You can:
- Execute workflows using the Execute button
- Add new nodes via context menu (right-click) or toolbar
- Configure node parameters by selecting/double-clicking nodes
- Save/load workflow JSON files using the toolbar buttons
- Real-time parameter editing with automatic validation
import { WorkflowProvider, WorkflowCanvas } from 'react-workflow-editor';
const App = () => {
const initialWorkflow = {
id: 'sample-workflow',
name: 'My Workflow',
nodes: [
{
id: 'trigger',
name: 'Manual Trigger',
type: 'manualTrigger',
position: [100, 200],
parameters: {}
}
],
connections: {}
};
return (
<WorkflowProvider initialWorkflow={initialWorkflow}>
<div className="h-screen">
<WorkflowCanvas />
</div>
</WorkflowProvider>
);
};
To add new node types:
- Create node definition in
src/nodeTypes/
:
// src/nodeTypes/MyCustomNode.ts
export const MyCustomNode: NodeTypeDefinition = {
displayName: 'My Custom Node',
name: 'myCustomNode',
group: ['transform'],
version: 1,
properties: [
{
displayName: 'My Parameter',
name: 'myParam',
type: 'string',
default: '',
description: 'Description of my parameter',
},
],
inputs: [{ type: 'main' }],
outputs: [{ type: 'main' }],
};
- Register the node type in
src/nodeTypes/index.ts
:
import { MyCustomNode } from './MyCustomNode';
export const NODE_TYPE_DEFINITIONS = {
// ... existing nodes
myCustomNode: MyCustomNode,
};
- The UI will automatically generate parameter forms and handle the node rendering.
src/
โโโ App.tsx # Main application component
โโโ main.tsx # Entry point
โโโ contexts/ # React Context providers
โ โโโ WorkflowContext.tsx # Main workflow state management
โ โโโ NodeContext.tsx # Individual node state management
โโโ components/
โ โโโ canvas/ # Canvas-related components
โ โ โโโ WorkflowCanvas.tsx
โ โโโ nodes/ # Node components
โ โ โโโ N8nNode.tsx
โ โโโ panels/ # Parameter panels
โ โโโ ParameterPanel.tsx
โ โโโ ParameterInput.tsx
โโโ nodeTypes/ # Node type definitions
โ โโโ ManualTrigger.ts
โ โโโ Set.ts
โ โโโ index.ts
โโโ types/ # TypeScript type definitions
โ โโโ context.ts
โ โโโ conversion.ts
โโโ utils/ # Utility functions
โ โโโ dataConversion.ts
โ โโโ cn.ts
โโโ hooks/ # Custom React hooks
โโโ useStrictContext.ts
โโโ useThrottle.ts
The project uses Tailwind CSS for styling with custom CSS variables for consistency:
- Colors: Primary, secondary, success, warning, danger variations
- Spacing:
--spacing-xs
through--spacing-5xl
- Typography: Font sizes, line heights, and weights
- Borders: Radius and border utilities
The NodeProvider
is essential for n8n compatibility:
- Mirrors n8n's provide/inject pattern from Vue
- Enables future parameter system expansions (conditional parameters, expressions, validation)
- Provides performance optimization (local re-rendering)
- Ensures type safety for node-specific operations
For detailed explanation, see: NodeProvider Architecture Documentation
Originally used EventBus pattern, but migrated to React's standard callback patterns for:
- Better React integration
- Improved type safety
- Simplified debugging
- Reduced dependencies
- Basic workflow editor
- ReactFlow integration
- Parameter panels
- Sample nodes
- Expression evaluation (
{{ $json.data }}
) - Conditional parameter display
- Resource loading (API endpoints, credentials)
- Advanced validation
- Custom node SDK
- Real workflow execution engine
- Plugin system
- Advanced debugging tools
- Performance analytics
- Collaborative editing
Contributions are welcome! Please read our contributing guidelines and:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- Follow existing code patterns and TypeScript conventions
- Maintain n8n compatibility in new features
- Add tests for new functionality
- Update documentation as needed
- Use meaningful commit messages
This project is licensed under the MIT License - see the LICENSE file for details.
- n8n - For the incredible workflow automation platform and design inspiration
- ReactFlow - For the excellent flow library
- React - For the amazing frontend framework
- Community contributors - For ideas, feedback, and contributions
- ๐ Documentation
- ๐ Issues
- ๐ฌ Discussions
Built with โค๏ธ for the workflow automation community