N8N Custom Nodes: Build Any Integration You Need
App doesn't have an N8N integration? Build it yourself in 30 minutes. This developer guide covers TypeScript node development, starter templates, and both declarative and programmatic approaches.
Why Build Custom N8N Nodes?
N8N has 1,145+ built-in integrations. But your internal CRM doesn't have a native node. Your proprietary billing system isn't supported. Your custom analytics API requires manual HTTP requests every time.
Solution: Build a custom node. Once created, it appears in N8N's node panel alongside official integrations. Reusable. Shareable. Native-like.
Time investment: 30 minutes for a basic API integration. 2-4 hours for complex nodes with multiple operations and credential management.
What Custom Nodes Enable
- ✓Connect to Any API: Wrap any REST API, GraphQL endpoint, or internal service
- ✓Custom Logic: Implement complex data transformations or business rules
- ✓Reusable Components: Build once, use across all workflows
- ✓Team Sharing: Package and share with your entire organization
- ✓Version Control: Track changes, collaborate via Git
- ✓Performance Optimization: Handle intensive tasks more efficiently than function nodes
Note: Custom nodes only work on self-hosted N8N instances for security reasons
Use cases: Internal APIs, proprietary databases, legacy systems, niche SaaS tools without official integrations, custom authentication flows, specialized data processing.
Development Approaches: Declarative vs Programmatic
N8N offers two node-building styles. Choose based on your use case complexity.
Declarative (Recommended)
Low-code approach using configuration objects. Best for standard REST API integrations.
Best For:
- • Simple API integrations
- • CRUD operations
- • Standard authentication (OAuth, API key)
- • Straightforward data transformations
- • RESTful endpoints
Advantages:
- • Faster development
- • Less code to maintain
- • Automatic UI generation
- • Easier to read and understand
Programmatic
Full TypeScript control. Best for complex logic and custom workflows.
Best For:
- • Complex business logic
- • Advanced error handling
- • Custom authentication flows
- • Multiple API endpoints
- • Performance-critical operations
Advantages:
- • Complete flexibility
- • Advanced error handling
- • Complex data processing
- • Custom UI components
For most use cases, start with declarative. You can always convert to programmatic later if you need more control.
Prerequisites & Setup
Required Tools
- •Node.js: v16 or higher (v22+ recommended)
- •npm: Latest version
- •Git: For version control
- •TypeScript Knowledge: Basic understanding required
- •Self-Hosted N8N: Custom nodes don't work on N8N Cloud
- •Code Editor: VS Code recommended (with TypeScript support)
Verify Installation
# Check Node.js version
node --version
# Should show v16+ (v22+ recommended)
# Check npm version
npm --version
# Verify Git
git --versionWant to learn AI Automations Reimagined and more?
Get all courses, templates, and automation systems for just $99/month
Start Learning for $99/monthQuick Start: Build Your First Custom Node (Method 1)
The fastest way to get started is with npm create @n8n/node, which scaffolds a complete node package.
Step 1: Scaffold New Node Package
# Create new node package
npm create @n8n/node
# Follow the prompts:
# - Package name: n8n-nodes-custom-crm
# - Node name: CustomCRM
# - Description: Integration for our internal CRM
# - Author: Your name
# Navigate to new directory
cd n8n-nodes-custom-crm
# Install dependencies
npm installThis creates a complete project structure with TypeScript configured, example nodes, credentials, linter, and all necessary tooling.
Step 2: Project Structure Overview
n8n-nodes-custom-crm/
├── credentials/ # Credential definitions
│ └── CustomCrmApi.credentials.ts
├── nodes/ # Node definitions
│ └── CustomCrm/
│ ├── CustomCrm.node.ts
│ └── CustomCrm.node.json
├── package.json
├── tsconfig.json
└── README.mdStep 3: Create Credential Definition
Most APIs require authentication. Define credentials first.
// credentials/CustomCrmApi.credentials.ts
import {
ICredentialType,
INodeProperties,
} from 'n8n-workflow';
export class CustomCrmApi implements ICredentialType {
name = 'customCrmApi';
displayName = 'Custom CRM API';
documentationUrl = 'https://docs.yourcrm.com/api';
properties: INodeProperties[] = [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string',
typeOptions: {
password: true,
},
default: '',
required: true,
},
{
displayName: 'Base URL',
name: 'baseUrl',
type: 'string',
default: 'https://api.yourcrm.com/v1',
required: true,
},
];
}Step 4: Create Node Definition (Declarative Style)
// nodes/CustomCrm/CustomCrm.node.ts
import {
INodeType,
INodeTypeDescription,
IExecuteFunctions,
INodeExecutionData,
} from 'n8n-workflow';
export class CustomCrm implements INodeType {
description: INodeTypeDescription = {
displayName: 'Custom CRM',
name: 'customCrm',
icon: 'file:customcrm.svg',
group: ['transform'],
version: 1,
description: 'Interact with Custom CRM API',
defaults: {
name: 'Custom CRM',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'customCrmApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Contact',
value: 'contact',
},
{
name: 'Company',
value: 'company',
},
],
default: 'contact',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: ['contact'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a contact',
},
{
name: 'Get',
value: 'get',
description: 'Get a contact',
},
{
name: 'Update',
value: 'update',
description: 'Update a contact',
},
],
default: 'create',
},
// Contact Create Fields
{
displayName: 'Email',
name: 'email',
type: 'string',
displayOptions: {
show: {
resource: ['contact'],
operation: ['create'],
},
},
default: '',
required: true,
description: 'Contact email address',
},
{
displayName: 'First Name',
name: 'firstName',
type: 'string',
displayOptions: {
show: {
resource: ['contact'],
operation: ['create'],
},
},
default: '',
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: INodeExecutionData[] = [];
const credentials = await this.getCredentials('customCrmApi');
const baseUrl = credentials.baseUrl as string;
const apiKey = credentials.apiKey as string;
for (let i = 0; i < items.length; i++) {
const resource = this.getNodeParameter('resource', i) as string;
const operation = this.getNodeParameter('operation', i) as string;
if (resource === 'contact') {
if (operation === 'create') {
const email = this.getNodeParameter('email', i) as string;
const firstName = this.getNodeParameter('firstName', i) as string;
const response = await this.helpers.request({
method: 'POST',
url: `${baseUrl}/contacts`,
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: {
email,
first_name: firstName,
},
json: true,
});
returnData.push({ json: response });
}
}
}
return [returnData];
}
}Step 5: Link Node to N8N (Development)
# Build the node package
npm run build
# Link to global npm
npm link
# In your N8N installation directory, link the node
cd ~/.n8n
npm link n8n-nodes-custom-crm
# Restart N8N with hot reload
n8n startYour custom node now appears in N8N's node panel. Add it to workflows like any native integration.
Alternative: Using the Starter Template (Method 2)
For more control and examples, use the official n8n-nodes-starter repository.
Clone the Starter Template
# Option 1: Use GitHub template feature
# Visit: https://github.com/n8n-io/n8n-nodes-starter
# Click "Use this template" → "Create a new repository"
# Option 2: Clone directly
git clone https://github.com/n8n-io/n8n-nodes-starter.git
cd n8n-nodes-starter
# Install dependencies
npm installThe starter template includes example nodes demonstrating both declarative and programmatic styles, credential examples, and complete tooling setup.
Explore Example Nodes
Included Examples:
- • ExampleNode.node.ts: Basic node structure
- • GitHubIssues.node.ts: Declarative style API integration
- • SendGrid.node.ts: Programmatic style with multiple operations
- • Credentials examples: API key, OAuth2, JWT patterns
Copy an example node that matches your use case, rename it, and modify for your API.
Testing & Debugging
Local Development Workflow
- 1.Build with Watch Mode:
npm run devAutomatically rebuilds when you save changes
- 2.Link to N8N:
npm link && cd ~/.n8n && npm link n8n-nodes-custom-crm - 3.Start N8N with Hot Reload:
n8n startNode changes appear after page refresh
- 4.Test in Workflow:
Create test workflow, add your node, execute, check output
Debugging Tips
- •Console Logging:
console.log('Debug:', this.getInputData());Logs appear in N8N terminal output
- •Error Messages:
N8N displays execution errors in workflow UI. Check terminal for stack traces.
- •TypeScript Errors:
npm run lintCatches type errors before runtime
Best Practices for Production Nodes
Security & Credentials
- ✓Never Hardcode Secrets: Always use credential definitions for API keys, tokens
- ✓Use Password Type: Set
typeOptions: password: truefor sensitive fields - ✓Environment Variables: Store development credentials in .env files (never commit)
Error Handling
try {
const response = await this.helpers.request({
method: 'POST',
url: `${baseUrl}/contacts`,
body: { email, firstName },
json: true,
});
returnData.push({ json: response });
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: { error: error.message },
error: error
});
} else {
throw new Error(`CRM API Error: ${error.message}`);
}
}Performance Optimization
- •Batch Operations: Process multiple items in single API call when possible
- •Rate Limiting: Implement delays for API rate limits
- •Pagination: Handle large result sets with pagination support
Code Quality
- •TypeScript Types: Use proper type definitions for all parameters
- •Documentation: Add clear descriptions to all node parameters
- •Validation: Validate required fields before API calls
- •Linting: Run
npm run lintbefore publishing
Publishing & Distribution
Option 1: Organization-Wide Distribution
For internal company use, publish to your organization's private npm registry or distribute via Git.
# Build production version
npm run build
# Publish to private npm registry
npm publish --registry=https://npm.yourcompany.com
# Or distribute via Git
git tag v1.0.0
git push origin v1.0.0
# Install on other N8N instances
npm install @yourcompany/n8n-nodes-custom-crmOption 2: Public npm Package
Share with the N8N community by publishing to public npm.
# Update package.json with community node keywords
{
"name": "n8n-nodes-custom-integration",
"version": "1.0.0",
"description": "N8N integration for CustomService",
"keywords": [
"n8n-community-node-package",
"n8n-node"
],
"n8n": {
"nodes": [
"dist/nodes/CustomIntegration/CustomIntegration.node.js"
],
"credentials": [
"dist/credentials/CustomIntegrationApi.credentials.js"
]
}
}
# Publish to npm
npm login
npm publish
# Users install with:
# npm install n8n-nodes-custom-integrationInstalling Custom Nodes on Self-Hosted N8N
# Via npm (recommended)
cd ~/.n8n
npm install n8n-nodes-custom-crm
# Via environment variable (Docker)
# In docker-compose.yml:
environment:
- N8N_CUSTOM_EXTENSIONS=/data/custom-nodes
# Then mount volume with custom nodes
volumes:
- ./custom-nodes:/data/custom-nodes
# Restart N8N
docker-compose restart n8nReal-World Examples
Example 1: Internal CRM Integration
Company: B2B SaaS (150 employees)
Challenge: Proprietary CRM system with no automation integrations
Solution: Custom N8N node with 12 operations (create/update contacts, companies, deals, notes)
Development Time: 6 hours total (2 hours initial, 4 hours refinement)
Result: 47 workflows now use the custom node, saving 15 hours weekly previously spent on manual data entry
Example 2: Analytics Data Pipeline
Company: E-commerce marketplace
Challenge: Custom analytics platform API needed batch data exports
Solution: Programmatic N8N node with pagination, rate limiting, and parallel processing
Development Time: 12 hours (complex error handling and optimization)
Result: Processes 500,000 records nightly, replaces $800/month third-party ETL tool
Example 3: Payment Gateway Reconciliation
Company: Fintech startup
Challenge: Regional payment provider with no N8N integration
Solution: Custom node with OAuth2 authentication, webhook support, transaction queries
Development Time: 8 hours (OAuth2 setup was most complex)
Result: Automated daily reconciliation, reduced accounting time from 4 hours to 15 minutes
Common Challenges & Solutions
Challenge: Node Not Appearing in N8N
Solution:
- • Run
npm run buildto compile TypeScript - • Verify
npm linkcompleted successfully - • Restart N8N completely (Ctrl+C and restart)
- • Check package.json has correct n8n.nodes path
Challenge: API Returns 401 Unauthorized
Solution:
- • Verify credential definition name matches node credential reference
- • Check API key format (some require "Bearer" prefix, others don't)
- • Test credentials with curl/Postman first to verify they work
- • Console.log credentials (temporarily) to ensure they're being passed
Challenge: TypeScript Type Errors
Solution:
- • Ensure
npm installran successfully to get type definitions - • Import correct types from
n8n-workflow - • Use
as stringtype assertions when needed - • Run
npm run lintto catch errors early
Challenge: Response Data Not Showing in Workflow
Solution:
- • Ensure you're pushing to returnData array:
returnData.push(json: response) - • Return array of arrays:
return [returnData] - • Verify API response is actually returning data (console.log it)
- • Check if response needs to be parsed (if not using
json: true)
Next Steps: Advanced Custom Node Development
Once you've built basic custom nodes, explore these advanced capabilities:
1. Webhook Support
Create nodes that listen for incoming webhooks, enabling real-time triggers for your custom integrations.
2. OAuth2 Authentication
Implement OAuth2 flows for services requiring user authorization, providing secure access to external APIs.
3. Custom UI Components
Build specialized input fields, dropdown options with dynamic loading, and custom validation logic.
4. Binary Data Handling
Process files, images, and documents within your custom nodes for complete workflow automation.
The Bottom Line
N8N's 1,145+ integrations cover most use cases. But when you need a custom integration for your internal systems, legacy APIs, or niche tools, custom nodes are the solution.
Development time: 30 minutes for basic API wrappers. 2-4 hours for complex nodes with multiple operations. 8-12 hours for advanced OAuth2 implementations.
The ROI is immediate: Workflows that previously required manual HTTP requests or Function nodes become reusable, maintainable integrations that your entire team can use.
When to Build Custom Nodes:
- • Internal APIs: Your company's proprietary systems
- • Legacy Systems: Old databases or applications without modern APIs
- • Niche SaaS Tools: Services without official N8N integrations
- • Reusability: Same API calls used across 3+ workflows
- • Team Distribution: Need to share integrations across organization
- • Performance: Function nodes too slow for intensive operations
Start simple with the declarative approach. Build one node. Test it. Deploy it. Then expand from there.
Your internal tools become first-class N8N citizens. That's powerful.
Want to master AI Automations Reimagined? Get it + 3 more complete courses
Complete Creator Academy - All Courses
Master Instagram growth, AI influencers, n8n automation, and digital products for just $99/month. Cancel anytime.
All 4 premium courses (Instagram, AI Influencers, Automation, Digital Products)
100+ hours of training content
Exclusive templates and workflows
Weekly live Q&A sessions
Private community access
New courses and updates included
Cancel anytime - no long-term commitment
✨ Includes: Instagram Ignited • AI Influencers Academy • AI Automations • Digital Products Empire