Artur
Artur
Founder

n8n Code Node: JavaScript and Python Examples

April 29, 2026

n8n-code-noden8n-javascriptn8n-pythonworkflow-automationn8n-examples

The Code Node fills gaps where built-in nodes fall short. You write custom JavaScript or Python, process data however you need, and pass it to the next step. This article gives you copy-paste examples for the most common use cases.

When to Use the Code Node

Built-in nodes handle standard operations. The Code Node handles everything else:

  • Transforming data structures that don't match what the next node expects

  • Filtering arrays based on complex conditions

  • Calling APIs that don't have a dedicated n8n integration

  • Working with dates, strings, or numbers in custom ways

  • Generating binary files like CSVs

If you're doing something a built-in node can do, use the built-in node. Code Nodes add complexity. Use them when you need logic that doesn't exist elsewhere.

JavaScript vs Python in the Code Node

Both languages work. JavaScript has better support in n8n's ecosystem - more examples, more community answers, and the expression syntax throughout n8n is JavaScript-based anyway.

FeatureJavaScriptPython
Data access$input.all()_input.all()
Return formatreturn itemsreturn items
External modulesLimited built-insLimited built-ins
Community examplesExtensiveGrowing
Expression compatibilityNativeRequires context switching

Python works fine for data processing. If you're more comfortable with Python, use it. But expect fewer examples to copy from.

Understanding $input and $items

This trips up most people. Here's the difference:

$input.all() - Returns all items from the previous node as an array. Each item has a json property containing the data.

$input.first() - Returns only the first item.

$input.item - In "Run Once for Each Item" mode, gives you the current item being processed.

Common mistake: trying to access $input.all().json directly. That doesn't work because $input.all() returns an array. You need $input.all()[0].json for the first item's data, or loop through the array.

// Wrong
const data = $input.all().json;

// Right
const items = $input.all();
const firstItemData = items[0].json;

In Python, replace $input with _input. Same methods, different prefix.

Example 1: Transform Data Structure

You have user records and need to restructure them for a CRM import.

Input:

[{"json": {"first": "John", "last": "Doe", "email": "john@example.com"}}]

JavaScript:

const items = $input.all();
return items.map(item => ({
  json: {
    fullName: `${item.json.first} ${item.json.last}`,
    contactEmail: item.json.email,
    source: "n8n-import"
  }
}));

Output:

[{"json": {"fullName": "John Doe", "contactEmail": "john@example.com", "source": "n8n-import"}}]

The key: always return an array of objects, each with a json property.

Example 2: Filter Arrays by Condition

Remove items that don't meet criteria. The Filter node works for simple cases, but complex logic needs code.

JavaScript - Filter adults only:

const items = $input.all();
return items.filter(item => item.json.age >= 18);

JavaScript - Multiple conditions:

const items = $input.all();
return items.filter(item => {
  const isActive = item.json.status === 'active';
  const hasEmail = item.json.email && item.json.email.includes('@');
  const recentLogin = new Date(item.json.lastLogin) > new Date('2026-01-01');
  return isActive && hasEmail && recentLogin;
});

Python equivalent:

items = _input.all()
return [item for item in items if item.json.get('age', 0) >= 18]

Example 3: Format Dates

Date handling is a constant pain point. n8n passes dates as strings, and downstream systems want specific formats.

JavaScript - ISO to readable:

const items = $input.all();
return items.map(item => {
  const date = new Date(item.json.createdAt);
  return {
    json: {
      ...item.json,
      formattedDate: date.toLocaleDateString('en-US', {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      })
    }
  };
});

JavaScript - Calculate age from birthdate:

const items = $input.all();
return items.map(item => {
  const birth = new Date(item.json.birthdate);
  const today = new Date();
  let age = today.getFullYear() - birth.getFullYear();
  const monthDiff = today.getMonth() - birth.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
    age--;
  }
  return {
    json: { ...item.json, age }
  };
});

Example 4: Call External APIs

When there's no built-in node for an API, use fetch in the Code Node.

JavaScript - Simple GET request:

const response = await fetch('https://api.genderize.io?name=john');
const data = await response.json();
return [{ json: data }];

JavaScript - POST with headers:

const items = $input.all();
const results = [];

for (const item of items) {
  const response = await fetch('https://api.example.com/enrich', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_TOKEN'
    },
    body: JSON.stringify({ email: item.json.email })
  });
  const enriched = await response.json();
  results.push({
    json: { ...item.json, ...enriched }
  });
}
return results;

Note: For APIs you call frequently, check if a community node exists first. Code Node API calls are harder to debug.

Example 5: Parse Nested JSON

APIs often return deeply nested structures. Flatten them for easier processing.

JavaScript:

const items = $input.all();
return items.map(item => {
  const data = item.json;
  return {
    json: {
      id: data.id,
      userName: data.user?.profile?.name || 'Unknown',
      userEmail: data.user?.contact?.email || null,
      orderTotal: data.order?.payment?.amount || 0,
      orderCurrency: data.order?.payment?.currency || 'USD'
    }
  };
});

The optional chaining (?.) prevents errors when nested properties don't exist.

Example 6: Aggregate and Calculate Statistics

Process all items to produce summary data - averages, totals, counts.

JavaScript:

const items = $input.all();
const ages = items.map(item => item.json.age).filter(a => typeof a === 'number');

const stats = {
  count: ages.length,
  total: ages.reduce((sum, age) => sum + age, 0),
  average: ages.length > 0 ? ages.reduce((sum, age) => sum + age, 0) / ages.length : 0,
  min: ages.length > 0 ? Math.min(...ages) : null,
  max: ages.length > 0 ? Math.max(...ages) : null
};

return [{ json: stats }];

This returns a single item with the aggregated results, not one item per input.

Example 7: Work with Binary Data - CSV Export

Generate a CSV file from your data.

JavaScript:

const items = $input.all();

// Build CSV content
const headers = ['name', 'email', 'age'];
const rows = items.map(item => 
  headers.map(h => `"${(item.json[h] || '').toString().replace(/"/g, '"')}"`).join(',')
);
const csv = [headers.join(','), ...rows].join('\n');

// Return as binary
return [{
  json: {},
  binary: {
    data: await this.helpers.prepareBinaryData(
      Buffer.from(csv, 'utf-8'),
      'export.csv',
      'text/csv'
    )
  }
}];

The binary property makes the file available for download or sending via email/storage nodes.

Example 8: Deduplicate by Key

Remove duplicate entries based on a specific field.

JavaScript:

const items = $input.all();
const seen = new Set();
const unique = [];

for (const item of items) {
  const key = item.json.email; // dedupe by email
  if (!seen.has(key)) {
    seen.add(key);
    unique.push(item);
  }
}
return unique;

Example 9: Batch Items into Groups

Split a large array into smaller batches for rate-limited APIs.

JavaScript:

const items = $input.all();
const batchSize = 10;
const batches = [];

for (let i = 0; i < items.length; i += batchSize) {
  batches.push({
    json: {
      batchNumber: Math.floor(i / batchSize) + 1,
      items: items.slice(i, i + batchSize).map(item => item.json)
    }
  });
}
return batches;

Each output item contains an array of up to 10 original items.

Example 10: Conditional Field Mapping

Map fields differently based on data values.

JavaScript:

const items = $input.all();
return items.map(item => {
  const data = item.json;
  let priority, handler;
  
  if (data.revenue > 100000) {
    priority = 'high';
    handler = 'enterprise-team';
  } else if (data.revenue > 10000) {
    priority = 'medium';
    handler = 'sales-team';
  } else {
    priority = 'low';
    handler = 'self-serve';
  }
  
  return {
    json: {
      ...data,
      priority,
      handler,
      processedAt: new Date().toISOString()
    }
  };
});

Common Errors and Fixes

"Cannot read property 'json' of undefined" You're accessing an item that doesn't exist. Check if your input array is empty before processing.

const items = $input.all();
if (items.length === 0) {
  return [{ json: { error: 'No input data' } }];
}

"items is not iterable" Your return value isn't an array. The Code Node must return an array, even for single items.

// Wrong
return { json: { result: 'done' } };

// Right
return [{ json: { result: 'done' } }];

Output shows as array in next node The Code Node output displays differently than you might expect. Each returned array item becomes a separate n8n item. If you return [{json: {data: [1,2,3]&#125;&#125;], that's one item with an array inside its json - not three items.

Python _input not working Make sure you selected Python in the Code Node language dropdown. The default is JavaScript.

FAQ

Can I use npm packages in the Code Node? Not directly. The Code Node has access to built-in Node.js modules and a few extras (like crypto), but you can't import arbitrary npm packages. For external libraries, you'd need to self-host n8n and modify the configuration.

Should I use "Run Once for All Items" or "Run Once for Each Item"? Use "Run Once for All Items" when you need to process items together - aggregations, deduplication, batching. Use "Run Once for Each Item" when each item is independent and you want simpler code that doesn't need to loop.

How do I debug Code Node errors? Add console.log() statements - they appear in the execution log. For complex debugging, return intermediate values as json output to inspect them, then fix your logic.

Is there a character or complexity limit? No hard character limit, but extremely long or computationally heavy code will timeout. If you're writing hundreds of lines, consider whether you should split the logic across multiple nodes.

Can I access data from nodes other than the previous one? Yes. Use $('NodeName').all() to get output from any earlier node by its name. Useful for merging data from different branches.


Need help building n8n workflows with custom logic? n8n Logic builds automation systems that handle complex data processing, API integrations, and business workflows.


n8n Code Node: JavaScript and Python Examples | n8nlogic