# Extension points — n8n-io/n8n

> Canonical page: https://codevetter.com/unpack/n8n/extension-points

# Extension points — n8n-io/n8n

Scanned commit 1a370b965c1fe438dfa58f371a01080eb9cca776 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

n8n is built around registries. Backend: @Command files under commands/, @RestController classes activated by ControllerRegistry, *.module.ts backend modules via ModuleRegistry, NodeLoader implementations fed through LoadNodesAndCredentials (package dirs, custom dirs via CUSTOM_EXTENSION_ENV, module-provided loaders), @OnPubSubEvent handlers, and ExternalHooks. Nodes/credentials plug in via the package.json 'n8n' manifest. Frontend: manifest registration functions (modals, component slots, capabilities, upgrade redirects, module routes). Node types themselves expose loadOptions/listSearch/credentialTest/webhookMethods hooks.
- New CLI commands: create a class file under packages/cli/src/commands/, decorate with @Command({name, description, flagsSchema (zod)}); CommandRegistry imports commands/<name>.js by convention and runs init/run/catch/finally. — [packages/cli/src/command-registry.ts#L45-104](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/command-registry.ts#L45-L104) [packages/cli/src/commands/start.ts#L60-66](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L60-L66)
- New REST endpoints: classes decorated @RestController('/path') with @Get/@Post/@Put/@Patch/@Delete methods are activated en masse by ControllerRegistry.activate(app); most are side-effect-imported at the top of server.ts. — [packages/cli/src/controller.registry.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/controller.registry.ts) [packages/cli/src/server.ts#L34-74](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L34-L74) [packages/cli/src/executions/executions.controller.ts#L22](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/executions/executions.controller.ts#L22)
- New backend module: a <name>.module.ts under packages/cli/src/modules (or packages/modules) is discovered by ModuleRegistry.loadModules; modules can register entities, node loaders, commands, pubsub handlers; membership is controlled by defaultModules + ModulesConfig enabled/disabled. — [packages/@n8n/backend-common/src/modules/module-registry.ts#L44-120](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/%40n8n/backend-common/src/modules/module-registry.ts#L44-L120)
- New integration node: implement INodeType (execute or declarative requestDefaults; poll/trigger/webhook/webhookMethods for triggers) under nodes/<Service>/, add the dist path to package.json 'n8n.nodes', and credentials under credentials/ with 'n8n.credentials' entries. — [packages/nodes-base/package.json#L35-36](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/nodes-base/package.json#L35-L36) [packages/nodes-base/nodes/Set/Set.node.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/nodes-base/nodes/Set/Set.node.ts) [packages/nodes-base/AGENTS.md](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/nodes-base/AGENTS.md)
- Community/custom node packages: LoadNodesAndCredentials supports DirectoryLoader, PackageDirectoryLoader, LazyPackageDirectoryLoader and CustomDirectoryLoader; CUSTOM_EXTENSION_ENV adds custom directories; module nodeLoaders are appended via moduleRegistry.nodeLoaders. — [packages/cli/src/load-nodes-and-credentials.ts#L14-30](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/load-nodes-and-credentials.ts#L14-L30) [packages/cli/src/load-nodes-and-credentials.ts#L103-137](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/load-nodes-and-credentials.ts#L103-L137)
- Cross-process hooks: @OnPubSubEvent/@OnLeaderTakeover/@OnLeaderStepdown/@OnShutdown decorators register handlers that PubSubRegistry.init() wires to Redis channels — but init must be re-called after modules load (explicit rewire comments in start.ts). — [packages/cli/src/commands/start.ts#L260-264](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L260-L264) [packages/cli/src/scaling/pubsub/pubsub.registry.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/scaling/pubsub/pubsub.registry.ts) [packages/cli/src/active-workflow-manager.ts#L6](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/active-workflow-manager.ts#L6)
- ExternalHooks.run('n8n.stop', 'frontend.settings', 'activeWorkflows.initialized', ...) lets deployments inject custom logic via EXTERNAL_HOOKS config. — [packages/cli/src/commands/start.ts#L110](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L110) [packages/cli/src/server.ts#L179](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L179) [packages/cli/src/external-hooks.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/external-hooks.ts)
- Frontend extension manifests: registerModuleRoutes(router), registerEagerModals, registerComponentSlots, registerShellCapabilities, registerUpgradeRedirectGuard in main.ts — frontend modules under packages/modules/<name>/frontend plug into the editor shell through these manifests. — [packages/frontend/editor-ui/src/main.ts#L51-65](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/frontend/editor-ui/src/main.ts#L51-L65) [packages/frontend/editor-ui/src/app/moduleInitializer/moduleInitializer.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/frontend/editor-ui/src/app/moduleInitializer/moduleInitializer.ts) [packages/frontend/editor-ui/src/app/modals.manifest.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/frontend/editor-ui/src/app/modals.manifest.ts)
- Auth is a strategy chain: AuthStrategyRegistry evaluates registered strategies in order (ApiKeyAuthStrategy first, SessionCookieAuthStrategy last); modules 'can append later during their own module initialization' (e.g. token-exchange JWT). — [packages/cli/src/server.ts#L191-201](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L191-L201) [packages/cli/src/services/auth-strategy.registry.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/services/auth-strategy.registry.ts)
- Node dynamic behavior hooks: methods.loadOptions, methods.listSearch, methods.credentialTest and resourceMapping let nodes serve dynamic UI data without a dedicated endpoint; DynamicNodeParametersController exposes them over REST. — [packages/nodes-base/AGENTS.md](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/nodes-base/AGENTS.md) [packages/cli/src/server.ts#L41](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L41)
- Execution context hooks: ExecutionContextHookRegistry (init'ed at the end of Start.init) lets modules hook execution-context establishment; establishExecutionContext in core consumes them. — [packages/cli/src/commands/start.ts#L318-319](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L318-L319) [packages/core/src/execution-engine/execution-context.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/core/src/execution-engine/execution-context.ts)
- System tasks: mainSystemTasks(globalConfig) returns task classes registered into SystemTaskMetadata and provisioned by SystemTaskRunner on the DurableScheduler — a registry for durable background jobs. — [packages/cli/src/commands/start.ts#L429-437](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L429-L437) [packages/cli/src/scheduling/durable-scheduler.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/scheduling/durable-scheduler.ts)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
