N8n code javascript
Skill neurawork-git/n8n-autopilot/skills/n8n-code-javascript
Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input/$json/$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.From its SKILL.md
npx -y skills add neurawork-git/n8n-autopilot --skill n8n-code-javascriptAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.0 KB, as published. Nobody here has run it
JavaScript Code Node
Expert guidance for writing JavaScript code in n8n Code nodes.
Quick Start
// 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;
Essential Rules
- Choose "Run Once for All Items" mode (recommended for most use cases)
- Access data:
$input.all(),$input.first(), or$input.item - CRITICAL: Must return
[{json: {...}}]format - CRITICAL: Webhook data is under
$json.body(not$jsondirectly) - Built-ins available: $helpers.httpRequest(), DateTime (Luxon), $jmespath()
When NOT to use a Code node (native-first)
Reach for a native node before writing JavaScript — Code nodes are harder to read, review, and they run V8 in-process (OOM risk on large data, see below). In a real production audit, Code nodes outnumbered native conditional nodes ~2.5:1 — much of it avoidable:
| If you are doing… | Use this native node, NOT Code |
|---|---|
| Branching on a condition | IF (2 branches) / Switch (n branches) |
| Dropping items by a rule | Filter |
| Setting / renaming / mapping fields | Set (Edit Fields) |
| Merging / combining streams | Merge |
| Aggregating into one item | Aggregate / Summarize |
| Looping over large batches | Loop Over Items (SplitInBatches) |
Memory / OOM (real production incident): a Code node that loads or iterates a large dataset — especially a full DB result set (>~10k rows), binary, or file contents — can spike the V8 heap (~3 GB cap) and crash the n8n pod (OOM). For large data: page/limit at the source, process in
SplitInBatches, or push the work into the database/native node instead of materializing it all in JS.
Use a Code node when the logic genuinely has no native equivalent (custom parsing, multi-field computation, shaping a bespoke payload).
Mode Selection Guide
Run Once for All Items (Recommended - Default)
Use for: aggregation, batch processing, transformations that have no native-node equivalent
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 }
}];
Run Once for Each Item
Use for: Specialized cases — per-item validation, independent operations
const item = $input.item;
return [{
json: { ...item.json, processed: true, processedAt: new Date().toISOString() }
}];
Decision: Need to compare multiple items? → All Items. Each item independent? → Each Item. Not sure? → All Items.
Data Access Patterns
// Most common: all items
const allItems = $input.all();
// Single result
const firstItem = $input.first();
const data = firstItem.json;
// Reference other nodes
const webhookData = $node["Webhook"].json;
const httpData = $node["HTTP Request"].json;
CRITICAL: Webhook Data Structure
Webhook data is nested under .body:
// ❌ WRONG
const name = $json.name;
// ✅ CORRECT
const name = $json.body.name;
const webhookData = $input.first().json.body;
Return Format Requirements
// ✅ Single result
return [{ json: { field1: value1 } }];
// ✅ Multiple results
return items.map(item => ({ json: { id: item.json.id, processed: true } }));
// ✅ Empty result
return [];
WRONG: return {json: {...}} (no array), return [{field: value}] (no json key)
Built-in Functions
$helpers.httpRequest()
const response = await $helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
headers: { 'Authorization': 'Bearer token' }
});
return [{ json: { data: response } }];
DateTime (Luxon)
const now = DateTime.now();
const formatted = now.toFormat('yyyy-MM-dd');
const tomorrow = now.plus({ days: 1 });
$jmespath()
const adults = $jmespath(data, 'users[?age >= `18`]');
const names = $jmespath(data, 'users[*].name');
Common Patterns
Aggregation
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 } }];
Filtering + Transformation
return $input.all()
.filter(item => item.json.status === 'active')
.map(item => ({ json: { id: item.json.id, name: item.json.name } }));
Error Handling
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 } }];
}
Top 5 Mistakes
- No return statement → Add
return items.map(item => ({json: item.json})); - Using
{{ }}in Code node → Use$json.fielddirectly (no braces) - Wrong return wrapper → Must be
[{json: {...}}], not{json: {...}} - Missing null checks → Use
item.json?.user?.email || 'fallback' - Webhook body →
$json.email❌ →$json.body.email✅
Best Practices
- Always validate input:
if (!items || items.length === 0) return []; - Use try-catch for async operations
- Prefer
map/filterover manual loops - Filter early, process late
- Debug with
console.log()
When to Use Code Node
✅ Complex transformations, custom calculations, API response parsing, multi-step conditionals, data aggregation
❌ Simple field mapping → Set node | Basic filtering → Filter node | HTTP requests → HTTP Request node