n8n-code-javascript

98
2
Source

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.

Install

mkdir -p .claude/skills/n8n-code-javascript && curl -L -o skill.zip "https://mcp.directory/api/skills/download/362" && unzip -o skill.zip -d .claude/skills/n8n-code-javascript && rm skill.zip

Installs to .claude/skills/n8n-code-javascript

About this skill

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

  1. Choose "Run Once for All Items" mode (recommended for most use cases)
  2. Access data: $input.all(), $input.first(), or $input.item
  3. CRITICAL: Must return [{json: {...}}] format
  4. CRITICAL: Webhook data is under $json.body (not $json directly)
  5. Built-ins available: $helpers.httpRequest(), DateTime (Luxon), $jmespath()

Mode Selection Guide

The Code node offers two execution modes. Choose based on your use case:

Run Once for All Items (Recommended - Default)

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:

  • ✅ Comparing items across the dataset
  • ✅ Calculating totals, averages, or statistics
  • ✅ Sorting or ranking items
  • ✅ Deduplication
  • ✅ Building aggregated reports
  • ✅ Combining data from multiple items

Run Once for Each Item

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:

  • ✅ Each item needs independent API call
  • ✅ Per-item validation with different error handling
  • ✅ Item-specific transformations based on item properties
  • ✅ When items must be processed separately for business logic

Decision Shortcut:

  • Need to look at multiple items? → Use "All Items" mode
  • Each item completely independent? → Use "Each Item" mode
  • Not sure? → Use "All Items" mode (you can always loop inside)

Data Access Patterns

Pattern 1: $input.all() - Most Common

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;

Pattern 2: $input.first() - Very Common

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()
  }
}];

Pattern 3: $input.item - Each Item Mode Only

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
  }
}];

Pattern 4: $node - Reference Other Nodes

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


Critical: Webhook Data Structure

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


Return Format Requirements

CRITICAL RULE: Always return array of objects with json property

Correct Return Formats

// ✅ 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 [];
}

Incorrect Return Formats

// ❌ 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


Common Patterns Overview

Based on production workflows, here are the most useful patterns:

1. Multi-Source Data Aggregation

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;

2. Filtering with Regex

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}}];

3. Data Transformation & Enrichment

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()
    }
  };
});

4. Top N Filtering & Ranking

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}));

5. Aggregation & Reporting

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


Error Prevention - Top 5 Mistakes

#1: Empty Code or Missing Return (Most Common)

// ❌ 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}));

#2: Expression Syntax Confusion

// ❌ 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;

#3: Incorrect Return Wrapper

// ❌ WRONG: Returning object instead of array
return {json: {result: 'success'}};

// ✅ CORRECT: Array wrapper required
return [{json: {result: 'success'}}];

#4: Missing Null Checks

// ❌ 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;

#5: Webhook Body Nesting

// ❌ 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


Built-in Functions & Helpers

$helpers.httpRequest()

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}}];

DateTime (Luxon)

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')
  }
}];

$jmespath()

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


Best Practices

1. Always Validate Input Data

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...

2. Use Try-Catch for 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
    }
  }];
}

3. Prefer Array Methods Over Loops

// ✅ 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}});
  }
}

4. Filter Early, Process Late

// ✅ 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');

5. Use Descriptive Variable Names

// ✅ 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);

6. Debug with console.log()

// 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;

When to Use Code Node

Use Code node when:

  • ✅ Complex transformations requiring multiple steps
  • ✅ Custom calculations or business logic
  • ✅ Recursive operations
  • ✅ API response parsing with complex structure
  • ✅ Multi-step conditionals
  • ✅ Data aggregation across items

Consider other nodes when:

  • ❌ Simple field mapping → Use Set node
  • ❌ Basic filtering → Use Filter node
  • ❌ Simple conditionals → Use IF or Switch node
  • ❌ HTTP requests only → Use HTTP Request node

Code node excels at: Complex logic that would require chaining many simple nodes


Integration with Other Skills

Works With:

n8n Expression Syntax:

  • Expressions use {{ }} syntax in other nodes
  • Code nodes use JavaScript directly (no {{ }})
  • When to use expressions vs code

n8n MCP Tools Expert:

  • How to find Code node: search_nodes({query: "code"})
  • Get configuration help: get_node_essentials("nodes-base.code")
  • Validate code: validate_node_operation()

n8n Node Configuration:

  • Mode selection (All Items vs Each Item)
  • Language selection (JavaScript vs Python)
  • Understanding property dependencies

n8n Workflow Patterns:

  • Code nodes in transformation step
  • Webhook → Code → API pattern
  • Error handling in workflows

n8n Validation Expert:

  • Validate Code node configuration
  • Handle validation errors
  • Auto-fix common issues

Quick Reference Checklist

Before deploying Code nodes, verify:

  • Code is not empty - Must have meaningful logic
  • Return statement exists - Must return array of objects
  • Proper return format - Each item: {json: {...}}
  • Data access correct - Using $input.all(), $input.first(), or $input.item
  • No n8n expressions - Use JavaScript template literals: `${value}`
  • Error handling - Guard clauses for null/undefined inputs
  • Webhook data - Access via .body if from webhook
  • Mode selection - "All Items" for most cases
  • Performance - Prefer map/filter over manual loops
  • Output consistent - All code paths return same structure

Additional Resources

Related Files

n8n Documentation


Ready 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.

More by czlonkowski

View all →

n8n-workflow-patterns

czlonkowski

Proven workflow architectural patterns from real n8n workflows. Use when building new workflows, designing workflow structure, choosing workflow patterns, planning workflow architecture, or asking about webhook processing, HTTP API integration, database operations, AI agent workflows, or scheduled tasks.

965

n8n-expression-syntax

czlonkowski

Validate n8n expression syntax and fix common errors. Use when writing n8n expressions, using {{}} syntax, accessing $json/$node variables, troubleshooting expression errors, or working with webhook data in workflows.

981

n8n-validation-expert

czlonkowski

Interpret validation errors and guide fixing them. Use when encountering validation errors, validation warnings, false positives, operator structure issues, or need help understanding validation results. Also use when asking about validation profiles, error types, or the validation loop process.

801

n8n-mcp-tools-expert

czlonkowski

Expert guide for using n8n-mcp MCP tools effectively. Use when searching for nodes, validating configurations, accessing templates, managing workflows, or using any n8n-mcp tool. Provides tool selection guidance, parameter formats, and common patterns.

1081

n8n-node-configuration

czlonkowski

Operation-aware node configuration guidance. Use when configuring nodes, understanding property dependencies, determining required fields, choosing between get_node_essentials and get_node_info, or learning common configuration patterns by node type.

921

n8n-code-python

czlonkowski

Write Python code in n8n Code nodes. Use when writing Python in n8n, using _input/_json/_node syntax, working with standard library, or need to understand Python limitations in n8n Code nodes.

661

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

297790

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

220415

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

215297

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

224234

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

175201

rust-coding-skill

UtakataKyosui

Guides Claude in writing idiomatic, efficient, well-structured Rust code using proper data modeling, traits, impl organization, macros, and build-speed best practices.

167173

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.