This page describes the structure of the Vue 3 single-page application in packages/frontend/editor-ui, covering application initialization, how backend settings reach the UI, the Pinia store layout, and how real-time push messages are handled.
For the workflow canvas and node interaction layer, see 6.2. For parameter input components and the expression editor, see 6.3. For the design system component library, see 6.4. For the AI Builder assistant frontend, see 5.1.
The editor UI is a Vue 3 SPA compiled and emitted to packages/frontend/editor-ui/dist. The backend (packages/cli) serves this dist folder statically. Before serving, the Start command pre-processes the HTML and JS files to inject instance-specific configuration.
Static asset compilation at startup replaces several placeholders in the dist output:
| Placeholder | Replaced With |
|---|---|
%CONFIG_TAGS% | Base64-encoded meta tags containing the REST endpoint path and Sentry DSN |
/{{BASE_PATH}}/ | The configured N8N_PATH value |
{{REST_ENDPOINT}} | The REST endpoint path (default: rest) |
</title> | </title> + <script> tags for external frontend hook URLs |
This is done in generateStaticAssets() and generateConfigTags() inside the Start command.
Sources: packages/cli/src/commands/start.ts123-187
The frontend needs server-side configuration (license state, SSO config, endpoint paths, feature flags, etc.) before it can render. This is delivered through the FrontendSettings type and a two-phase load.
FrontendService in packages/cli/src/services/frontend.service.ts is the backend service that assembles the FrontendSettings object. It is decorated with @Service() and injected into the DI container.
Key methods:
| Method | Returns | Notes |
|---|---|---|
initSettings() | void | Builds the this.settings object from GlobalConfig, license, SSO state, etc. |
getSettings() | FrontendSettings | Refreshes dynamic values (enterprise flags, license, SSO) before returning |
getPublicSettings(includeMfaSettings) | PublicFrontendSettings | Returns a smaller subset for unauthenticated pages |
generateTypes() | void | Writes types/nodes.json, types/credentials.json, types/node-versions.json to the static cache dir |
getModuleSettings() | object | Returns per-module settings from ModuleRegistry |
getSettings() refreshes several dynamic fields on every call:
License)LicenseState)MfaService)License)N8N_ENV_FEAT_* env vars)config.getEnv)Sources: packages/cli/src/services/frontend.service.ts1-664 packages/@n8n/api-types/src/frontend-settings.ts66-233
The canonical type is FrontendSettings from @n8n/api-types. A reduced version, PublicFrontendSettings, is used for unauthenticated pages. The settingsMode field distinguishes them:
'authenticated' ā full settings, returned by getSettings()'public' ā subset for login/setup pages, returned by getPublicSettings()Sources: packages/@n8n/api-types/src/frontend-settings.ts66-233 packages/cli/src/services/frontend.service.ts38-102
Settings loading pipeline ā from GlobalConfig to the frontend store
Sources: packages/cli/src/services/frontend.service.ts402-549 packages/cli/src/commands/start.ts144-187
The editor-ui uses Pinia for all shared state. Stores are defined with defineStore() using a string ID from the STORES enum (exported from @n8n/stores). The composition API style (() => { ... }) is used throughout.
Pinia store dependency map (NodeView context)
Sources: packages/frontend/editor-ui/src/app/views/NodeView.vue1-210 packages/frontend/editor-ui/src/features/ai/assistant/builder.store.ts1-70
| Store file | Hook | Primary responsibility |
|---|---|---|
app/stores/settings.store | useSettingsStore | FrontendSettings, initialized flag, settings mode |
app/stores/ui.store | useUIStore | Active modals, sidebar open/close, active view tabs |
app/stores/workflows.store | useWorkflowsStore | Current open workflow: nodes, connections, run data, pin data |
app/stores/workflowsList.store | useWorkflowsListStore | Workflow list/pagination for the home view |
app/stores/nodeTypes.store | useNodeTypesStore | INodeTypeDescription registry, lazy-loaded per type |
app/stores/canvas.store | useCanvasStore | Canvas viewport transform, zoom level |
app/stores/history.store | useHistoryStore | Undo/redo command stack (BulkCommand) |
app/stores/pushConnection.store | usePushConnectionStore | SSE/WebSocket connection state and message dispatch |
app/stores/posthog.store | usePostHog | PostHog feature flag state |
app/stores/logs.store | useLogsStore | Execution log panel open/close and log data |
app/stores/focusPanel.store | useFocusPanelStore | Focus sidebar panel open state |
app/stores/workflowSave.store | useWorkflowSaveStore | Autosave state (AutoSaveState enum) |
features/credentials/credentials.store | useCredentialsStore | Credential list, current credential |
features/ndv/shared/ndv.store | useNDVStore | Active node for Node Details View, tab state |
features/shared/nodeCreator/nodeCreator.store | useNodeCreatorStore | Node creator panel open state, view history |
features/shared/tags/tags.store | useTagsStore | Workflow tags |
features/collaboration/projects/projects.store | useProjectsStore | Team projects list, current project |
features/collaboration/collaboration/collaboration.store | useCollaborationStore | Real-time collaborators, shouldBeReadOnly, isCurrentTabWriter |
features/settings/users/users.store | useUsersStore | Current user, user list |
features/settings/environments.ee/environments.store | useEnvironmentsStore | Variables/environment EE |
features/integrations/sourceControl.ee/sourceControl.store | useSourceControlStore | Branch, branchReadOnly, source control preferences |
features/ai/assistant/builder.store | useBuilderStore | AI Builder chat messages, streaming state, credits |
features/ai/assistant/assistant.store | useAssistantStore | Ask-mode AI assistant state |
features/ai/assistant/chatPanel.store | useChatPanelStore | Chat panel width, open state |
features/workflows/workflowHistory/workflowHistory.store | useWorkflowHistoryStore | Workflow version history list |
features/workflows/canvas/experimental/experimentalNdv.store | useExperimentalNdvStore | Experimental NDV feature flags |
@n8n/stores/useRootStore | useRootStore | pushRef, restApiContext, instance base URL |
@n8n/stores/useAgentRequestStore | useAgentRequestStore | Persists agent request query state |
Sources: packages/frontend/editor-ui/src/app/views/NodeView.vue182-205 packages/frontend/editor-ui/src/features/ai/assistant/builder.store.ts128-209 packages/frontend/editor-ui/src/features/ai/assistant/components/Agent/AskAssistantBuild.vue56-68
The backend can push real-time events to the browser. The transport is selected by the pushBackend field in FrontendSettings (either 'sse' or 'websocket'). This is controlled by PushConfig in the backend and exposed through FrontendService.initSettings().
usePushConnectionStore (at packages/frontend/editor-ui/src/app/stores/pushConnection.store.ts) manages the lifecycle:
PushMessage payloads to the relevant stores or event busesPush connection message flow
Sources: packages/frontend/editor-ui/src/app/views/NodeView.vue104-105 packages/cli/src/services/frontend.service.ts291-292 packages/@n8n/api-types/src/frontend-settings.ts164
The pushBackend value originates from PushConfig (injected into FrontendService) and is served in FrontendSettings as pushBackend: 'sse' | 'websocket'. The frontend reads this value from the settings store at startup to decide which connection type to open.
packages/frontend/editor-ui/src/Interface.ts defines nearly all frontend-specific TypeScript interfaces not covered by @n8n/api-types. Notable types:
| Type | Purpose |
|---|---|
INodeUi | Extends INode with UI-only fields: position, color, notes, issues, pinData |
IWorkflowDb | Full workflow object as known to the frontend (nodes, connections, tags, sharing, etc.) |
ISettingsState | Shape of the settings store state |
INodeCreatorState | Node creator panel state (filter, selected view, open source) |
WorkflowResource / CredentialsResource | List-view resource types for the home page table |
INodeCreateElement | Union of all node creator item types (node, category, section, link, etc.) |
ModalState / Modals | Registry of all open modals and their data |
IStartRunData | Payload sent when triggering a manual workflow run |
Sources: packages/frontend/editor-ui/src/Interface.ts1-780
Many UI behaviors are gated behind fields in FrontendSettings. The settings store (useSettingsStore) exposes computed helpers that components consume. The pattern is:
FrontendService.getSettings() runs on the backend and assembles the object.GET /rest/settings after login.settings.enterprise.sharing, settings.mfa.enabled).Fields that gate major UI features:
| Field | Controls |
|---|---|
enterprise.sharing | Workflow/credential sharing UI |
enterprise.sourceControl | Source control menu item |
enterprise.variables | Variables settings section |
aiAssistant.enabled | AI assistant sidebar |
aiBuilder.enabled | AI Builder tab |
mfa.enabled / mfa.enforced | MFA setup prompts |
communityNodesEnabled | Community package management |
pushBackend | SSE vs. WebSocket push connection |
settingsMode | 'public' (unauthenticated) vs. 'authenticated' initialization path |
envFeatureFlags | N8N_ENV_FEAT_* environment-driven feature flags |
Sources: packages/@n8n/api-types/src/frontend-settings.ts66-233 packages/cli/src/services/frontend.service.ts450-548 packages/frontend/editor-ui/src/__tests__/defaults.ts1-80
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.