Code Node's Role
When visual nodes can't handle your needs (complex transforms, regex, math), Code Node is your ultimate escape hatch.
graph TB
subgraph "n8n Processing Hierarchy"
L1[🟢 Built-in Nodes
Set / If / Merge
70% of scenarios]
L2[🟡 Expressions
double curly json.field
20% of scenarios]
L3[🔴 Code Node
JS / Python
Remaining 10%]
end
L1 --> L2 --> L3
style L3 fill:#ff6d5b,stroke:#e55a4e,color:#fff1. Two Run Modes
Run Once for All Items (Recommended Default)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// $input.all() returns all Items — you control iteration
// Best for: aggregation, sorting, dedup, grouping
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const allItems = $input.all();
// Sort by price descending
const sorted = allItems.sort((a, b) => b.json.price - a.json.price);
// Deduplicate by email
const seen = new Set();
const unique = allItems.filter(item => {
if (seen.has(item.json.email)) return false;
seen.add(item.json.email);
return true;
});
return unique; // Must return Item array
Run Once for Each Item
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// $input.item is "this one Item" — n8n handles iteration
// Best for: per-item transforms with no cross-item dependencies
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const item = $input.item;
const phone = item.json.phone;
const masked = phone.slice(0, 3) + '****' + phone.slice(-4);
return {
json: {
...item.json,
maskedPhone: masked,
processedAt: new Date().toISOString()
}
};
2. Built-in Variables
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Quick reference table
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 📌 Current node data
$input.all() // All input Items
$input.first() // First Item
$input.item // Current Item (Each mode)
// 📌 Cross-node reference (⭐ Very powerful!)
$('Set').all() // All outputs from "Set" node
$('HTTP Request').first().json // First Item's JSON from another node
// 📌 Workflow metadata
$execution.id // Current execution ID
$workflow.name // Workflow name
$now.toISO() // Current ISO time
$env.MY_SECRET_KEY // Environment variable (secure!)
3. Practical Examples
CSV Parser
const csv = $input.first().json.csvData;
const lines = csv.split('\n');
const headers = lines[0].split(',');
const items = lines.slice(1).map(line => {
const values = line.split(',');
const obj = {};
headers.forEach((h, i) => { obj[h.trim()] = values[i]?.trim(); });
return { json: obj };
});
return items;
Group-By Aggregation
const items = $input.all();
const grouped = items.reduce((acc, item) => {
const city = item.json.city;
if (!acc[city]) acc[city] = { city, count: 0, total: 0 };
acc[city].count += 1;
acc[city].total += item.json.amount;
return acc;
}, {});
return Object.values(grouped).map(g => ({ json: g }));
Async Fetch
// n8n Code Node natively supports async/await with fetch
const response = await fetch('https://api.github.com/repos/n8n-io/n8n');
const data = await response.json();
return [{ json: { stars: data.stargazers_count } }];
4. Python Mode (n8n 2.0+)
# Switch Language to "Python" in node settings
# Requires N8N_RUNNERS_ENABLED=true (Task Runner)
items = _input.all()
result = []
for item in items:
data = item["json"]
result.append({"json": {
"original": data["name"],
"uppercased": data["name"].upper(),
"length": len(data["name"]),
}})
return result
Security Model
graph TB
subgraph "Code Node Sandbox"
Code[💻 Your Code]
Code -->|"✅ Allowed"| A1[fetch / HTTP]
Code -->|"✅ Allowed"| A2[JSON ops]
Code -->|"❌ Blocked"| D1[File system access]
Code -->|"❌ Blocked"| D2[require external modules]
Code -->|"❌ Blocked"| D3[child_process]
end
style Code fill:#ff6d5b,stroke:#e55a4e,color:#fffNext Episode
In Ep 10, we'll speed-run n8n's most useful built-in utility nodes — Merge, Set, Edit Image, Date & Time — completing the everyday developer toolkit.