AGENTS.md
packages/nodes-base/AGENTS.mdAGENTS.md
Quality
89/100
Scores the file, not the repository.Length
670 words
23 headings · 2 code blocksRepository
199k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# AGENTS.md23Guidance for node development in the nodes-base package.45## Node Structure67Every node implements the `INodeType` interface with:8- `description: INodeTypeDescription` - Node metadata and UI configuration9- `execute?()` - For programmatic nodes10- `poll?()` - For polling triggers (set `polling: true` in description)11- `trigger?()` - For generic triggers12- `webhook?()` - For webhook triggers13- `webhookMethods?` - Webhook lifecycle (checkExists, create, delete)14- `methods?` - loadOptions, listSearch, credentialTest, resourceMapping1516## Node Types1718### Programmatic Nodes19Use `execute` function for custom logic. Example: `nodes/Discord/v2/DiscordV2.node.ts`2021### Declarative Nodes22Use `requestDefaults` and routing configuration instead of `execute`. Example: `nodes/Okta/Okta.node.ts`2324### Trigger Nodes25- **Webhook triggers**: Implement `webhook` and `webhookMethods` (checkExists, create, delete). Example: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`26- **Polling triggers**: Set `polling: true` and implement `poll`. Use `getWorkflowStaticData('node')` to persist state. Example: `nodes/Google/Gmail/GmailTrigger.node.ts`27- **Generic triggers**: Implement `trigger` function. Example: `nodes/MQTT/MqttTrigger.node.ts`2829## Node Parameters3031Common parameter types:32- `string` - Text input33- `options` - Dropdown (static or dynamic via `loadOptionsMethod`)34- `resourceLocator` - Select by list, ID, or URL35- `collection` - Key-value pairs36- `fixedCollection` - Structured collections3738Use `displayOptions` to show/hide fields based on other parameters. Use `noDataExpression: true` for resource/operation selectors.3940## Versioning4142- **Light versioning**: Use version arrays in description: `version: [3, 3.1, 3.2]`43- **Full versioning**: Use `VersionedNodeType` class with separate version implementations. Example: `nodes/Set/Set.node.ts`4445## Credentials4647Credentials are defined in `credentials/` directory and implement `ICredentialType`:48- `name` - Internal identifier49- `displayName` - Human-readable name50- `properties` - Credential fields51- `authenticate` - Authentication configuration (generic or custom function)52- `test` - Credential test request5354Nodes can test credentials via `methods.credentialTest`.5556## Testing5758### Unit Tests59- Use `vitest-mock-extended` for mocking interfaces60- Use `nock` for HTTP mocking61- Mock all external dependencies62- Test happy paths, error handling, edge cases, and binary data6364### Workflow Tests65- Use `NodeTestHarness` with JSON workflow definitions66- Mock external APIs with nock67- Use `pnpm test` for running tests. Example: `cd packages/nodes-base/ && pnpm test TestFileName`6869## Common Development Tasks7071### Creating a New Node721. Create directory: `nodes/YourService/`732. Create `YourService.node.ts` implementing `INodeType`743. Add icon SVG files in node directory754. Define credentials in `credentials/` if needed765. Write tests following testing guidelines776. Register in `package.json` nodes array if needed7879### Adding Dynamic Options80Add `loadOptionsMethod` to parameter's `typeOptions` and implement method in `methods.loadOptions`.8182### Adding Resource Locator83Change parameter type to `'resourceLocator'`, define modes (list, id, url), add `searchListMethod` for list mode, add `extractValue` regex for URL mode.8485## Best Practices8687### TypeScript88- Never use `any` type - use proper types or `unknown`89- Avoid type casting with `as` - use type guards instead90- Define interfaces for API responses9192### Error Handling93- Use `NodeOperationError` for user-facing errors94- Use `NodeApiError` for API-related errors95- Support `continueOnFail` option when appropriate9697### Security9899User input is untrusted. In nodes it arrives mainly through100`this.getNodeParameter(...)` (and incoming `item.json`), and a workflow author101controls these values.102103**Never use an untrusted value as a computed object key in an assignment.** A104value such as `__proto__`, `constructor`, or `prototype` pollutes the prototype105chain:106107```ts108// UNSAFE — `table`/`key` come from this.getNodeParameter(...)109if (acc[table] === undefined) acc[table] = {};110acc[table][key] = value;111```112113Route dynamic-key writes through the `n8n-workflow` helpers, or build the114accumulator as a `Map` / `Object.create(null)`:115116```ts117import { setSafeObjectProperty, isSafeObjectProperty } from 'n8n-workflow';118119if (isSafeObjectProperty(table) && acc[table] === undefined) {120 setSafeObjectProperty(acc, table, {});121}122```123124This only applies to dynamic-key **writes** (grouping/aggregating rows by a125user-chosen column is the common case). Reads like `const x = obj[key]` are126safe. Reference usage: `nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts`.127128### Code Organization129- Separate operation/field descriptions into separate files130- Create reusable API request helpers in GenericFunctions131- Use kebab-case for files, PascalCase for classes132133### UI/UX134- Use clear `displayName` and `description` fields135- Set sensible default values136- Use `displayOptions` to show/hide fields conditionally137138## Example Nodes139140- Declarative: `nodes/Okta/Okta.node.ts`141- Programmatic: `nodes/Discord/v2/DiscordV2.node.ts`142- Webhook Trigger: `nodes/Microsoft/Teams/MicrosoftTeamsTrigger.node.ts`143- Polling Trigger: `nodes/Google/Gmail/GmailTrigger.node.ts`144- Generic Trigger: `nodes/MQTT/MqttTrigger.node.ts`145- Versioned: `nodes/Set/Set.node.ts`146
Also in n8n-io/n8n
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8n.agents/skills/AGENTS.md · 199k | AGENTS.md | setuparchagent-behaviour | 58/100 | 3 days ago | |
| n8n-io/n8n.github/CLAUDE.md · 199k | CLAUDE.md | styleagent-behaviour | 48/100 | 3 days ago | |
| n8n-io/n8nAGENTS.md · 199k | AGENTS.md | setupbuildtestlint-format+8 | 96/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/ai-workflow-builder.ee/AGENTS.md · 199k | AGENTS.md | agent-behaviour | 53/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/db/AGENTS.md · 199k | AGENTS.md | database | 39/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/engine/AGENTS.md · 199k | AGENTS.md | archdo-not | 59/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/instance-ai/CLAUDE.md · 199k | CLAUDE.md | buildteststyletesting-strategy+1 | 89/100 | 3 days ago | |
| n8n-io/n8npackages/cli/AGENTS.md · 199k | AGENTS.md | lint-format | 55/100 | 3 days ago | |
| n8n-io/n8npackages/cli/src/modules/n8n-packages/CLAUDE.md · 199k | CLAUDE.md | stylearchdependenciesmonorepo+2 | 69/100 | 3 days ago | |
| n8n-io/n8npackages/frontend/AGENTS.md · 199k | AGENTS.md | style | 40/100 | 3 days ago | |
| n8n-io/n8npackages/frontend/editor-ui/src/app/stores/workflowDocument/CLAUDE.md · 199k | CLAUDE.md | styleagent-behaviour | 58/100 | 3 days ago | |
| n8n-io/n8npackages/testing/playwright/AGENTS.md · 199k | AGENTS.md | setupbuildtestlint-format+8 | 96/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| n8n-io/n8nscripts/instance-seeding/AGENTS.md · 199k | AGENTS.md | setupstyledo-not | 65/100 | 3 days ago |
Diff against .agents/skills/AGENTS.md Diff against .github/CLAUDE.md Diff against AGENTS.md Diff against packages/@n8n/ai-workflow-builder.ee/AGENTS.md Diff against packages/@n8n/db/AGENTS.md Diff against packages/@n8n/engine/AGENTS.md Diff against packages/@n8n/instance-ai/CLAUDE.md Diff against packages/cli/AGENTS.md Diff against packages/cli/src/modules/n8n-packages/CLAUDE.md Diff against packages/frontend/AGENTS.md Diff against packages/frontend/editor-ui/src/app/stores/workflowDocument/CLAUDE.md Diff against packages/testing/playwright/AGENTS.md Diff against packages/@n8n/agents/AGENTS.md Diff against scripts/instance-seeding/AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | 3 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 3 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 67k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| aaif-goose/gooseAGENTS.md · 52k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| elastic/elasticsearchx-pack/plugin/inference/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+3 | 100/100 | 3 days ago |
