CodeVetter · Repo Unpack · System map
n8n-io/n8n
pnpm 12.4.2 / Turbo monorepo requiring Node >=24. The `n8n` binary (packages/cli/bin/n8n) loads config, then CommandRegistry dispatches a @Command-decorated class; `start` boots an Express Server (AbstractServer subclass), `worker` runs Bull consumers, `webhook` runs a dedicated webhook process. Execution is handled by n8n-core's WorkflowExecute; persistence is TypeORM in @n8n/db over SQLite/Postgres; the editor is a Vue 3 + Vite + Pinia SPA served from a generated static cache. Queue mode adds Redis pub/sub + Bull queues and optional multi-main leaders.
- Monorepo is managed by pnpm workspaces with Turbo task orchestration; packageManager is pinned to pnpm@12.4.2 and Node >=24 is required.
- Process entry is packages/cli/bin/n8n: it checks the Node version, loads dotenv, requires dist/config early (entity column types depend on GlobalConfig.database.type), then resolves CommandRegistry from the @n8n/di Container and calls execute().
- CommandRegistry maps argv[2] (default 'start') to a file under dist/commands, imports it so its @Command decorator registers metadata, parses flags with a per-command zod schema, then runs the class lifecycle init() -> run() -> catch() -> finally().
- packages/cli is the 'n8n' npm package: an Express server (Server extends AbstractServer), ~40 decorator-registered REST controllers, plus modules, scaling, webhooks, task-runner, and push subsystems, all wired through @n8n/di's Container.get().
- n8n-core (packages/core) owns the execution engine: WorkflowExecute (3168-line file) drives node runs, alongside node-execution-contexts, partial-execution-utils, triggers-and-pollers, nodes-loader, and encryption.
- n8n-workflow (packages/workflow) holds the shared type model (INode, IRunData, IConnections), the Workflow class (nodes + connectionsBySourceNode/ByDestinationNode + expression), and the Tournament-based expression evaluator.
- n8n-nodes-base ships built-in integrations: ~560 *.node.ts files under nodes/ and ~409 *.credentials.ts files under credentials/, enumerated in the package.json 'n8n.nodes'/'n8n.credentials' arrays that the DirectoryLoader consumes.
- @n8n/db is the persistence layer: ~50 entities (WorkflowEntity, ExecutionEntity/ExecutionData, CredentialsEntity, WebhookEntity, User, Project, SharedWorkflow, Settings, DeploymentKey, ScheduledJob...) plus sqlite/postgres migration trees; DbConnection wraps the TypeORM DataSource and runs migrations under a Postgres advisory lock.
- The editor frontend is a Vue 3 + Vite + Pinia app (n8n-editor-ui) that mounts App.vue with a router, i18n, telemetry/sentry plugins, and a set of manifest registration functions for module-provided UI.
- Deployment modes: 'regular' single process; 'queue' mode splits into main(s), workers, and webhook processes communicating over Redis pub/sub (Publisher/Subscriber/PubSubRegistry) with Bull job queues; multi-main is licensed and leader-elected via MultiMainSetup.
- Backend functionality is split into 'modules': ModuleRegistry loads <name>.module.js for ~32 default modules (insights, external-secrets, community-packages, data-table, oauth-server, mcp, source-control, sso-oidc, sso-saml, ldap, chat-hub, instance-ai, ...), gated by ModulesConfig enabled/disabled lists.
- Configuration is centralized in @n8n/config's GlobalConfig: config classes use @Env decorators mapping env vars (e.g. N8N_RUNNERS_MODE, N8N_RUNNERS_BROKER_PORT) onto typed fields.
- Deployment artifacts: Dockerfiles under docker/images (n8n, n8n-base, runners, node-pc, engine) and root scripts build:docker/dockerize-n8n.mjs produce the shippable image.