n8n-code-javascript by czlonkowski/n8n-skills
npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-code-javascript在 n8n 代码节点中编写 JavaScript 代码的专家指南。
// Basic template for Code nodes
const items = $input.all();
// Process data
const processed = items.map(item => ({
json: {
...item.json,
processed: true,
timestamp: new Date().toISOString()
}
}));
return processed;
$input.all()、$input.first() 或 $input.item[{json: {...}}] 格式$json.body 下(而不是直接位于 下)广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
$json代码节点提供两种执行模式。请根据您的用例选择:
适用于: 95% 的用例
工作原理:无论输入数量多少,代码仅执行一次
数据访问:$input.all() 或 items 数组
最适合:聚合、过滤、批处理、转换、使用所有数据进行 API 调用
性能:对于多个项目更快(单次执行)
// Example: Calculate total from all items const allItems = $input.all(); const total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{ json: { total, count: allItems.length, average: total / allItems.length } }];
何时使用:
适用于: 仅限特殊情况
工作原理:代码为每个输入项目单独执行
数据访问:$input.item 或 $item
最适合:特定于项目的逻辑、独立操作、每个项目的验证
性能:对于大型数据集较慢(多次执行)
// Example: Add processing timestamp to each item const item = $input.item;
return [{ json: { ...item.json, processed: true, processedAt: new Date().toISOString() } }];
何时使用:
决策捷径:
适用于:处理数组、批处理操作、聚合
// Get all items from previous node
const allItems = $input.all();
// Filter, map, reduce as needed
const valid = allItems.filter(item => item.json.status === 'active');
const mapped = valid.map(item => ({
json: {
id: item.json.id,
name: item.json.name
}
}));
return mapped;
适用于:处理单个对象、API 响应、先进先出
// Get first item only
const firstItem = $input.first();
const data = firstItem.json;
return [{
json: {
result: processData(data),
processedAt: new Date().toISOString()
}
}];
适用于:在“对每个项目运行一次”模式下
// Current item in loop (Each Item mode only)
const currentItem = $input.item;
return [{
json: {
...currentItem.json,
itemProcessed: true
}
}];
适用于:需要工作流中特定节点的数据
// Get output from specific node
const webhookData = $node["Webhook"].json;
const httpData = $node["HTTP Request"].json;
return [{
json: {
combined: {
webhook: webhookData,
api: httpData
}
}
}];
参见:DATA_ACCESS.md 获取完整指南
最常见的错误:Webhook 数据嵌套在 .body 下
// ❌ WRONG - Will return undefined
const name = $json.name;
const email = $json.email;
// ✅ CORRECT - Webhook data is under .body
const name = $json.body.name;
const email = $json.body.email;
// Or with $input
const webhookData = $input.first().json.body;
const name = webhookData.name;
原因:Webhook 节点将所有请求数据包装在 body 属性下。这包括 POST 数据、查询参数和 JSON 负载。
参见:DATA_ACCESS.md 获取完整的 webhook 结构详情
关键规则:始终返回包含 json 属性的对象数组
// ✅ Single result
return [{
json: {
field1: value1,
field2: value2
}
}];
// ✅ Multiple results
return [
{json: {id: 1, data: 'first'}},
{json: {id: 2, data: 'second'}}
];
// ✅ Transformed array
const transformed = $input.all()
.filter(item => item.json.valid)
.map(item => ({
json: {
id: item.json.id,
processed: true
}
}));
return transformed;
// ✅ Empty result (when no data to return)
return [];
// ✅ Conditional return
if (shouldProcess) {
return [{json: processedData}];
} else {
return [];
}
// ❌ WRONG: Object without array wrapper
return {
json: {field: value}
};
// ❌ WRONG: Array without json wrapper
return [{field: value}];
// ❌ WRONG: Plain string
return "processed";
// ❌ WRONG: Raw data without mapping
return $input.all(); // Missing .map()
// ❌ WRONG: Incomplete structure
return [{data: value}]; // Should be {json: value}
重要性:后续节点期望数组格式。不正确的格式会导致工作流执行失败。
参见:ERROR_PATTERNS.md #3 获取详细的错误解决方案
基于生产工作流,以下是最有用的模式:
合并来自多个 API、webhook 或节点的数据
const allItems = $input.all();
const results = [];
for (const item of allItems) {
const sourceName = item.json.name || 'Unknown';
// Parse source-specific structure
if (sourceName === 'API1' && item.json.data) {
results.push({
json: {
title: item.json.data.title,
source: 'API1'
}
});
}
}
return results;
从文本中提取模式、提及或关键词
const pattern = /\b([A-Z]{2,5})\b/g;
const matches = {};
for (const item of $input.all()) {
const text = item.json.text;
const found = text.match(pattern);
if (found) {
found.forEach(match => {
matches[match] = (matches[match] || 0) + 1;
});
}
}
return [{json: {matches}}];
映射字段、标准化格式、添加计算字段
const items = $input.all();
return items.map(item => {
const data = item.json;
const nameParts = data.name.split(' ');
return {
json: {
first_name: nameParts[0],
last_name: nameParts.slice(1).join(' '),
email: data.email,
created_at: new Date().toISOString()
}
};
});
排序并限制结果
const items = $input.all();
const topItems = items
.sort((a, b) => (b.json.score || 0) - (a.json.score || 0))
.slice(0, 10);
return topItems.map(item => ({json: item.json}));
求和、计数、分组数据
const items = $input.all();
const total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{
json: {
total,
count: items.length,
average: total / items.length,
timestamp: new Date().toISOString()
}
}];
参见:COMMON_PATTERNS.md 获取 10 个详细的生产模式
// ❌ WRONG: No return statement
const items = $input.all();
// ... processing code ...
// Forgot to return!
// ✅ CORRECT: Always return data
const items = $input.all();
// ... processing ...
return items.map(item => ({json: item.json}));
// ❌ WRONG: Using n8n expression syntax in code
const value = "{{ $json.field }}";
// ✅ CORRECT: Use JavaScript template literals
const value = `${$json.field}`;
// ✅ CORRECT: Direct access
const value = $input.first().json.field;
// ❌ WRONG: Returning object instead of array
return {json: {result: 'success'}};
// ✅ CORRECT: Array wrapper required
return [{json: {result: 'success'}}];
// ❌ WRONG: Crashes if field doesn't exist
const value = item.json.user.email;
// ✅ CORRECT: Safe access with optional chaining
const value = item.json?.user?.email || 'no-email@example.com';
// ✅ CORRECT: Guard clause
if (!item.json.user) {
return [];
}
const value = item.json.user.email;
// ❌ WRONG: Direct access to webhook data
const email = $json.email;
// ✅ CORRECT: Webhook data under .body
const email = $json.body.email;
参见:ERROR_PATTERNS.md 获取全面的错误指南
在代码内部发起 HTTP 请求:
const response = await $helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json'
}
});
return [{json: {data: response}}];
日期和时间操作:
// Current time
const now = DateTime.now();
// Format dates
const formatted = now.toFormat('yyyy-MM-dd');
const iso = now.toISO();
// Date arithmetic
const tomorrow = now.plus({days: 1});
const lastWeek = now.minus({weeks: 1});
return [{
json: {
today: formatted,
tomorrow: tomorrow.toFormat('yyyy-MM-dd')
}
}];
查询 JSON 结构:
const data = $input.first().json;
// Filter array
const adults = $jmespath(data, 'users[?age >= `18`]');
// Extract fields
const names = $jmespath(data, 'users[*].name');
return [{json: {adults, names}}];
参见:BUILTIN_FUNCTIONS.md 获取完整参考
const items = $input.all();
// Check if data exists
if (!items || items.length === 0) {
return [];
}
// Validate structure
if (!items[0].json) {
return [{json: {error: 'Invalid input format'}}];
}
// Continue processing...
try {
const response = await $helpers.httpRequest({
url: 'https://api.example.com/data'
});
return [{json: {success: true, data: response}}];
} catch (error) {
return [{
json: {
success: false,
error: error.message
}
}];
}
// ✅ GOOD: Functional approach
const processed = $input.all()
.filter(item => item.json.valid)
.map(item => ({json: {id: item.json.id}}));
// ❌ SLOWER: Manual loop
const processed = [];
for (const item of $input.all()) {
if (item.json.valid) {
processed.push({json: {id: item.json.id}});
}
}
// ✅ GOOD: Filter first to reduce processing
const processed = $input.all()
.filter(item => item.json.status === 'active') // Reduce dataset first
.map(item => expensiveTransformation(item)); // Then transform
// ❌ WASTEFUL: Transform everything, then filter
const processed = $input.all()
.map(item => expensiveTransformation(item)) // Wastes CPU
.filter(item => item.json.status === 'active');
// ✅ GOOD: Clear intent
const activeUsers = $input.all().filter(item => item.json.active);
const totalRevenue = activeUsers.reduce((sum, user) => sum + user.json.revenue, 0);
// ❌ BAD: Unclear purpose
const a = $input.all().filter(item => item.json.active);
const t = a.reduce((s, u) => s + u.json.revenue, 0);
// Debug statements appear in browser console
const items = $input.all();
console.log(`Processing ${items.length} items`);
for (const item of items) {
console.log('Item data:', item.json);
// Process...
}
return result;
在以下情况下使用代码节点:
在以下情况下考虑使用其他节点:
代码节点擅长于:需要链接许多简单节点的复杂逻辑
n8n 表达式语法:
{{ }} 语法{{ }})n8n MCP 工具专家:
search_nodes({query: "code"})get_node_essentials("nodes-base.code")validate_node_operation()n8n 节点配置:
n8n 工作流模式:
n8n 验证专家:
部署代码节点前,请验证:
{json: {...}}$input.all()、$input.first() 或 $input.item${value}.body 访问准备好编写 n8n 代码节点中的 JavaScript 了! 从简单的转换开始,使用错误模式指南避免常见错误,并参考模式库获取生产就绪的示例。
每周安装数
1.1K
代码仓库
GitHub 星标数
3.3K
首次出现
Jan 20, 2026
安全审计
安装于
opencode929
gemini-cli895
codex862
github-copilot781
claude-code715
cursor711
Expert guidance for writing JavaScript code in n8n Code nodes.
// Basic template for Code nodes
const items = $input.all();
// Process data
const processed = items.map(item => ({
json: {
...item.json,
processed: true,
timestamp: new Date().toISOString()
}
}));
return processed;
$input.all(), $input.first(), or $input.item[{json: {...}}] format$json.body (not $json directly)The Code node offers two execution modes. Choose based on your use case:
Use this mode for: 95% of use cases
How it works : Code executes once regardless of input count
Data access : $input.all() or items array
Best for : Aggregation, filtering, batch processing, transformations, API calls with all data
Performance : Faster for multiple items (single execution)
// Example: Calculate total from all items const allItems = $input.all(); const total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{ json: { total, count: allItems.length, average: total / allItems.length } }];
When to use:
Use this mode for: Specialized cases only
How it works : Code executes separately for each input item
Data access : $input.item or $item
Best for : Item-specific logic, independent operations, per-item validation
Performance : Slower for large datasets (multiple executions)
// Example: Add processing timestamp to each item const item = $input.item;
return [{ json: { ...item.json, processed: true, processedAt: new Date().toISOString() } }];
When to use:
Decision Shortcut:
Use when : Processing arrays, batch operations, aggregations
// Get all items from previous node
const allItems = $input.all();
// Filter, map, reduce as needed
const valid = allItems.filter(item => item.json.status === 'active');
const mapped = valid.map(item => ({
json: {
id: item.json.id,
name: item.json.name
}
}));
return mapped;
Use when : Working with single objects, API responses, first-in-first-out
// Get first item only
const firstItem = $input.first();
const data = firstItem.json;
return [{
json: {
result: processData(data),
processedAt: new Date().toISOString()
}
}];
Use when : In "Run Once for Each Item" mode
// Current item in loop (Each Item mode only)
const currentItem = $input.item;
return [{
json: {
...currentItem.json,
itemProcessed: true
}
}];
Use when : Need data from specific nodes in workflow
// Get output from specific node
const webhookData = $node["Webhook"].json;
const httpData = $node["HTTP Request"].json;
return [{
json: {
combined: {
webhook: webhookData,
api: httpData
}
}
}];
See : DATA_ACCESS.md for comprehensive guide
MOST COMMON MISTAKE : Webhook data is nested under .body
// ❌ WRONG - Will return undefined
const name = $json.name;
const email = $json.email;
// ✅ CORRECT - Webhook data is under .body
const name = $json.body.name;
const email = $json.body.email;
// Or with $input
const webhookData = $input.first().json.body;
const name = webhookData.name;
Why : Webhook node wraps all request data under body property. This includes POST data, query parameters, and JSON payloads.
See : DATA_ACCESS.md for full webhook structure details
CRITICAL RULE : Always return array of objects with json property
// ✅ Single result
return [{
json: {
field1: value1,
field2: value2
}
}];
// ✅ Multiple results
return [
{json: {id: 1, data: 'first'}},
{json: {id: 2, data: 'second'}}
];
// ✅ Transformed array
const transformed = $input.all()
.filter(item => item.json.valid)
.map(item => ({
json: {
id: item.json.id,
processed: true
}
}));
return transformed;
// ✅ Empty result (when no data to return)
return [];
// ✅ Conditional return
if (shouldProcess) {
return [{json: processedData}];
} else {
return [];
}
// ❌ WRONG: Object without array wrapper
return {
json: {field: value}
};
// ❌ WRONG: Array without json wrapper
return [{field: value}];
// ❌ WRONG: Plain string
return "processed";
// ❌ WRONG: Raw data without mapping
return $input.all(); // Missing .map()
// ❌ WRONG: Incomplete structure
return [{data: value}]; // Should be {json: value}
Why it matters : Next nodes expect array format. Incorrect format causes workflow execution to fail.
See : ERROR_PATTERNS.md #3 for detailed error solutions
Based on production workflows, here are the most useful patterns:
Combine data from multiple APIs, webhooks, or nodes
const allItems = $input.all();
const results = [];
for (const item of allItems) {
const sourceName = item.json.name || 'Unknown';
// Parse source-specific structure
if (sourceName === 'API1' && item.json.data) {
results.push({
json: {
title: item.json.data.title,
source: 'API1'
}
});
}
}
return results;
Extract patterns, mentions, or keywords from text
const pattern = /\b([A-Z]{2,5})\b/g;
const matches = {};
for (const item of $input.all()) {
const text = item.json.text;
const found = text.match(pattern);
if (found) {
found.forEach(match => {
matches[match] = (matches[match] || 0) + 1;
});
}
}
return [{json: {matches}}];
Map fields, normalize formats, add computed fields
const items = $input.all();
return items.map(item => {
const data = item.json;
const nameParts = data.name.split(' ');
return {
json: {
first_name: nameParts[0],
last_name: nameParts.slice(1).join(' '),
email: data.email,
created_at: new Date().toISOString()
}
};
});
Sort and limit results
const items = $input.all();
const topItems = items
.sort((a, b) => (b.json.score || 0) - (a.json.score || 0))
.slice(0, 10);
return topItems.map(item => ({json: item.json}));
Sum, count, group data
const items = $input.all();
const total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{
json: {
total,
count: items.length,
average: total / items.length,
timestamp: new Date().toISOString()
}
}];
See : COMMON_PATTERNS.md for 10 detailed production patterns
// ❌ WRONG: No return statement
const items = $input.all();
// ... processing code ...
// Forgot to return!
// ✅ CORRECT: Always return data
const items = $input.all();
// ... processing ...
return items.map(item => ({json: item.json}));
// ❌ WRONG: Using n8n expression syntax in code
const value = "{{ $json.field }}";
// ✅ CORRECT: Use JavaScript template literals
const value = `${$json.field}`;
// ✅ CORRECT: Direct access
const value = $input.first().json.field;
// ❌ WRONG: Returning object instead of array
return {json: {result: 'success'}};
// ✅ CORRECT: Array wrapper required
return [{json: {result: 'success'}}];
// ❌ WRONG: Crashes if field doesn't exist
const value = item.json.user.email;
// ✅ CORRECT: Safe access with optional chaining
const value = item.json?.user?.email || 'no-email@example.com';
// ✅ CORRECT: Guard clause
if (!item.json.user) {
return [];
}
const value = item.json.user.email;
// ❌ WRONG: Direct access to webhook data
const email = $json.email;
// ✅ CORRECT: Webhook data under .body
const email = $json.body.email;
See : ERROR_PATTERNS.md for comprehensive error guide
Make HTTP requests from within code:
const response = await $helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json'
}
});
return [{json: {data: response}}];
Date and time operations:
// Current time
const now = DateTime.now();
// Format dates
const formatted = now.toFormat('yyyy-MM-dd');
const iso = now.toISO();
// Date arithmetic
const tomorrow = now.plus({days: 1});
const lastWeek = now.minus({weeks: 1});
return [{
json: {
today: formatted,
tomorrow: tomorrow.toFormat('yyyy-MM-dd')
}
}];
Query JSON structures:
const data = $input.first().json;
// Filter array
const adults = $jmespath(data, 'users[?age >= `18`]');
// Extract fields
const names = $jmespath(data, 'users[*].name');
return [{json: {adults, names}}];
See : BUILTIN_FUNCTIONS.md for complete reference
const items = $input.all();
// Check if data exists
if (!items || items.length === 0) {
return [];
}
// Validate structure
if (!items[0].json) {
return [{json: {error: 'Invalid input format'}}];
}
// Continue processing...
try {
const response = await $helpers.httpRequest({
url: 'https://api.example.com/data'
});
return [{json: {success: true, data: response}}];
} catch (error) {
return [{
json: {
success: false,
error: error.message
}
}];
}
// ✅ GOOD: Functional approach
const processed = $input.all()
.filter(item => item.json.valid)
.map(item => ({json: {id: item.json.id}}));
// ❌ SLOWER: Manual loop
const processed = [];
for (const item of $input.all()) {
if (item.json.valid) {
processed.push({json: {id: item.json.id}});
}
}
// ✅ GOOD: Filter first to reduce processing
const processed = $input.all()
.filter(item => item.json.status === 'active') // Reduce dataset first
.map(item => expensiveTransformation(item)); // Then transform
// ❌ WASTEFUL: Transform everything, then filter
const processed = $input.all()
.map(item => expensiveTransformation(item)) // Wastes CPU
.filter(item => item.json.status === 'active');
// ✅ GOOD: Clear intent
const activeUsers = $input.all().filter(item => item.json.active);
const totalRevenue = activeUsers.reduce((sum, user) => sum + user.json.revenue, 0);
// ❌ BAD: Unclear purpose
const a = $input.all().filter(item => item.json.active);
const t = a.reduce((s, u) => s + u.json.revenue, 0);
// Debug statements appear in browser console
const items = $input.all();
console.log(`Processing ${items.length} items`);
for (const item of items) {
console.log('Item data:', item.json);
// Process...
}
return result;
Use Code node when:
Consider other nodes when:
Code node excels at : Complex logic that would require chaining many simple nodes
n8n Expression Syntax :
{{ }} syntax in other nodes{{ }})n8n MCP Tools Expert :
search_nodes({query: "code"})get_node_essentials("nodes-base.code")validate_node_operation()n8n Node Configuration :
n8n Workflow Patterns :
n8n Validation Expert :
Before deploying Code nodes, verify:
{json: {...}}$input.all(), $input.first(), or $input.item${value}.body if from webhookReady to write JavaScript in n8n Code nodes! Start with simple transformations, use the error patterns guide to avoid common mistakes, and reference the pattern library for production-ready examples.
Weekly Installs
1.1K
Repository
GitHub Stars
3.3K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode929
gemini-cli895
codex862
github-copilot781
claude-code715
cursor711
97,600 周安装