Frontend Architecture
Relevant source files
The following files were used as context for generating this wiki page:
- AGENTS.md
- CONTRIBUTING.md
- packages/frontend/editor-ui/src/main.ts
- packages/frontend/editor-ui/src/app/App.vue
- packages/frontend/editor-ui/src/app/router.ts
- packages/frontend/@n8n/design-system/src/plugin.ts
- packages/frontend/editor-ui/src/app/components/layouts/EmptyStateLayout.vue
- packages/frontend/editor-ui/src/app/components/WhatsNewModal.test.ts
The n8n frontend is a modern, modular single-page application (SPA) built with Vue 3 and TypeScript. It serves as the primary user interface for creating, managing, and executing workflows. The architecture is designed for extensibility and maintainability, leveraging a monorepo structure to manage shared packages like a dedicated design system, internationalization (i18n), and shared type definitions.
The core frontend application, editor-ui, integrates several key technologies: Vue 3 for the component model, Pinia for state management, and Vue Router for navigation. This structure allows for a clear separation of concerns, with a centralized design system ensuring UI consistency across the platform. The application is built using Vite, providing a fast development experience with hot module replacement.
Sources: AGENTS.md, CONTRIBUTING.md
Key Frontend Packages
The frontend architecture is distributed across several packages within the n8n monorepo, managed by pnpm workspaces. This modular approach promotes code reuse and separation of concerns.
| Package | Description |
|---|---|
packages/editor-ui | The main Vue 3 frontend application for the workflow editor. |
packages/@n8n/design-system | A dedicated Vue component library that provides reusable UI components and ensures visual consistency. |
packages/@n8n/i18n | Handles internationalization for all UI text, allowing for multi-language support. |
packages/@n8n/api-types | Contains shared TypeScript interfaces and types used by both the frontend and backend to ensure type safety across the stack. |
Sources: AGENTS.md:28-40
Application Bootstrap Process
The application's entry point is packages/frontend/editor-ui/src/main.ts. This file is responsible for initializing the Vue application instance, setting up essential plugins, and mounting the root component to the DOM.
The bootstrap sequence is as follows:
- A new Vue application is created using
createApp(App). - Essential plugins are installed via
app.use():- Pinia: For centralized state management.
- Router: For handling client-side navigation.
- Design System: To register all reusable UI components globally.
- i18n: To provide internationalization services.
- The application is mounted to the
#appelement in the DOM.
This diagram illustrates the frontend application's startup flow.
Code Example: main.ts
// packages/frontend/editor-ui/src/main.ts:8-17
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { designSystem } from '@n8n/design-system';
import { i18n } from '@n8n/i18n';
import App from './app/App.vue';
import { router } from './app/router';
createApp(App)
.use(createPinia())
.use(router)
.use(designSystem)
.use(i18n)
.mount('#app');
This snippet shows the concise setup chain, where the root App component is instantiated and configured with all necessary plugins before being mounted.
Sources: packages/frontend/editor-ui/src/main.ts:8-17
Core Components and Structure
Root Component: App.vue
The file packages/frontend/editor-ui/src/app/App.vue defines the root Vue component for the entire application. It acts as the main layout container, holding the <RouterView /> component which dynamically renders the component associated with the current route.
Its primary responsibilities are:
- Providing a persistent layout structure.
- Displaying global UI elements like modals and notifications that exist outside of specific page views.
- Serving as the entry point for the component tree.
Sources: packages/frontend/editor-ui/src/app/App.vue
Design System
The @n8n/design-system package is a crucial part of the frontend architecture. It centralizes all reusable UI components to maintain a consistent look and feel.
The system is implemented as a Vue plugin. The plugin.ts file defines an install function that iterates through a collection of components (e.g., N8nCard, N8nHeading, N8nIcon) and registers them globally with the Vue application. This makes them available for use in any part of the editor-ui without needing to be imported individually.
This diagram shows how a component like EmptyStateLayout.vue utilizes components from the design system.
Routing
Client-side routing is managed by vue-router. The configuration is located in packages/frontend/editor-ui/src/app/router.ts. It defines the mapping between URL paths and the Vue components that should be rendered.
The router is created using createRouter and uses a web history implementation (createWebHistory). Routes are defined in an array, with each route object specifying a path, name, and component. Lazy loading is used for route components (e.g., component: () => import(...)) to improve initial load performance by splitting code into smaller chunks.
Key Routes
| Path | Name | Component | Description |
|---|---|---|---|
/ | Home | HomePage.vue | The main landing page. |
/workflow/new | NewWorkflow | WorkflowPage.vue | The editor page for a new, unsaved workflow. |
/workflow/:id | Workflow | WorkflowPage.vue | The editor page for an existing workflow. |
/workflows | Workflows | WorkflowsPage.vue | The page listing all available workflows. |
/templates | Templates | TemplatesPage.vue | The page for browsing workflow templates. |
/settings/users | Users | UsersPage.vue | The user management settings page. |
Sources: packages/frontend/editor-ui/src/app/router.ts:13-118
This diagram illustrates the relationship between URL paths and their corresponding Vue components as defined in the router.
State Management
State management in the n8n frontend is handled by Pinia. It provides a centralized store for application-wide state, making it accessible and manageable from any component. While the specific store definitions are not in the provided files, their usage is evident in components and tests.
For example, EmptyStateLayout.vue and WhatsNewModal.test.ts demonstrate the use of several stores:
useUsersStore: Manages current user data and permissions.useProjectsStore: Manages project-related data.useUIStore: Manages the state of UI elements like modals.useVersionsStore: Manages application version information.useReadyToRunStore: Manages state for the "Ready to Run" feature.
This pattern of using composable store functions (use...Store) is standard for Pinia and allows components to reactively access and modify shared state.
This diagram shows how EmptyStateLayout.vue depends on multiple Pinia stores to render its content.
Summary
The n8n frontend architecture is a well-structured system built on the Vue 3 ecosystem. Its key strengths lie in its modularity, achieved through a pnpm monorepo that separates concerns into distinct packages for the UI editor, design system, i18n, and API types. The use of Pinia for state management and Vue Router for navigation provides a robust foundation for a complex single-page application. This architecture promotes code reusability, maintainability, and a consistent user experience.
Sources: AGENTS.md, CONTRIBUTING.md, packages/frontend/editor-ui/src/main.ts