Canvas Engine
Relevant source files
The following files were used as context for generating this wiki page:
- packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue
- packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue
- packages/frontend/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue
- cypress/e2e/group2/12-canvas.cy.ts
- packages/frontend/editor-ui/src/composables/useCanvasMapping.ts
- packages/frontend/editor-ui/src/composables/useCanvas.ts
- packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeAIPrompt.vue
The Canvas Engine is the core of n8n's visual workflow editor. It provides a dynamic and interactive surface where users build, manage, and debug their automation workflows. Built on top of the @vue-flow/core library, it renders nodes and their connections, handles user interactions, and reflects the state of the workflow in real-time. The engine is designed to be extensible, supporting various node types, including standard nodes, sticky notes, and specialized UI elements like the AI prompt.
This system is primarily composed of Vue components and composables that work together to translate n8n's workflow data model into a visual representation. Key responsibilities include rendering nodes and edges, managing canvas state (zoom, pan, selection), handling user inputs (drag-and-drop, context menus), and communicating state changes back to the application.
Architecture
The Canvas Engine follows a component-based architecture, with a main wrapper component orchestrating several smaller, specialized components for nodes, edges, and handles. Data flows from the parent workflow store, is transformed by a mapping composable, and then passed as props to the rendering components.
Component Hierarchy
The following diagram illustrates the primary component structure of the Canvas Engine.
This diagram shows that WorkflowCanvas.vue is the top-level component, which contains the main Canvas.vue (based on Vue Flow). The Canvas.vue component is responsible for rendering CanvasNode.vue and CanvasEdge.vue components for each node and connection in the workflow. CanvasNode.vue further breaks down into renderers, handles, and toolbars.
Sources: packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue, packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue
Data Flow
The engine transforms the raw workflow data from the database (IWorkflowDb) into a format suitable for rendering by Vue Flow. This is handled by the useCanvasMapping composable.
This flow ensures a clear separation between the application's data model and the view model required by the rendering library. During workflow execution, the mapped nodes and connections are throttled to optimize performance.
Sources: packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue:52-59, packages/frontend/editor-ui/src/composables/useCanvasMapping.ts
Core Components
WorkflowCanvas.vue
This is the main entry point for the canvas feature. It acts as a wrapper around the generic Canvas.vue component, feeding it the necessary workflow data.
Key Props:
| Prop | Type | Description |
|---|---|---|
id | string | A unique ID for the Vue Flow instance, defaults to 'canvas'. |
workflow | IWorkflowDb | The main workflow data object containing nodes and connections. |
workflowObject | Workflow | The instantiated Workflow class object. |
eventBus | EventBus<CanvasEventBus> | An event bus for communication between canvas components. |
readOnly | boolean | If true, disables user interactions like moving nodes or creating connections. |
executing | boolean | A flag indicating if the workflow is currently executing, which enables throttling for performance. |
suppressInteraction | boolean | A flag to suppress all user interactions on the canvas. |
When a workflow is executing, WorkflowCanvas.vue uses throttledRef to update the nodes and connections, preventing performance degradation from rapid UI updates.
Sources: packages/frontend/editor-ui/src/components/canvas/WorkflowCanvas.vue:18-40, 65-66
CanvasNode.vue
This component is responsible for rendering a single node on the canvas. It's a highly dynamic component that adapts based on the node's data, type, and state.
Key Features:
- Render Types: It can render different types of nodes using
CanvasNodeRenderer.vue, such as default nodes, sticky notes, or special UI prompts likeCanvasNodeAIPrompt.vue. - Handles: It renders input and output handles (
CanvasHandleRenderer.vue) for creating connections. The position and visibility of these handles are calculated dynamically. - Toolbar: A
CanvasNodeToolbar.vueis displayed on hover or focus, providing actions like delete, disable, and run. - State Management: It visually reflects the node's state (selected, hovered, disabled, issues).
- Event Bus: It uses a local event bus (
canvasNodeEventBus) to receive actions targeted at it, such asupdate:node:class.
Sources: packages/frontend/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue, packages/frontend/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeAIPrompt.vue
CanvasEdge.vue
This component renders the connection between two nodes. It displays the status of the data flow (e.g., success, running) and can include a toolbar for actions like deleting the connection or adding a new node in between.
Sources: packages/frontend/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue
State and Interactions
useCanvas.ts
This composable manages the global state of the canvas that is not tied to a specific node or workflow.
Managed State:
| State Property | Type | Description |
|---|---|---|
connectingHandle | Ref<ConnectingHandle | null> | Stores information about the handle being dragged to create a new connection. |
isExperimentalNdvActive | ComputedRef<boolean> | A feature flag for the new Node Display View (NDV). |
zoom | Ref<number> | The current zoom level of the canvas. |
selection | Ref<{ nodes: string[], edges: string[] }> | The IDs of currently selected nodes and edges. |
Sources: packages/frontend/editor-ui/src/composables/useCanvas.ts
User Interactions
The canvas supports a wide range of user interactions, which are tested in the e2e test suites.
Common Actions:
- Adding Nodes: Users can add nodes via a central plus button, a node's output handle, or by right-clicking the canvas.
- Deleting Nodes: Nodes can be deleted via the context menu (
Delete), the backspace/delete key, or by selecting multiple nodes and deleting them. - Connecting Nodes: Dragging from an output handle of one node to an input handle of another.
- Zoom & Pan: The canvas can be zoomed in/out and panned. A "zoom to fit" option is also available.
- Disabling Nodes: Nodes can be toggled between an active and disabled state using the context menu or the 'd' key.
- Renaming Nodes: Nodes can be renamed using the F2 key or the context menu.
- Duplicating Nodes: Nodes can be duplicated using
Ctrl/Cmd+Dor the context menu.
The following sequence diagram shows the process of deleting a node via the context menu, as described in the tests.