Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | 245% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 222% | 0% |
| case-08 | ✓→✓ | = Same ✓ | 349% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 305% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 281% | 0% |
Expert guidance for writing JavaScript code in n8n Code nodes.
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(), 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
$input.all() or items arrayjavascript// 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
$input.item or $itemjavascript// 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
javascript// 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
javascript// 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
javascript// 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
javascript// 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
javascript// ❌ 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
javascript// ✅ 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 []; }
javascript// ❌ 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
javascriptconst 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
javascriptconst 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
javascriptconst 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
javascriptconst 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
javascriptconst 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
javascript// ❌ 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}));
javascript// ❌ 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;
javascript// ❌ WRONG: Returning object instead of array return {json: {result: 'success'}}; // ✅ CORRECT: Array wrapper required return [{json: {result: 'success'}}];
javascript// ❌ 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;
javascript// ❌ 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:
javascriptconst 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:
javascript// 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:
javascriptconst 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
javascriptconst 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...
javascripttry { 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 } }]; }
javascript// ✅ 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}}); } }
javascript// ✅ 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');
javascript// ✅ 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);
javascript// 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.
Other measured skills in the registry, with their headline benchmark lift.