# How to Use the Code Node in n8n for Custom JavaScript and Python

- Tool: n8n
- Difficulty: Beginner
- Time required: 15-20 minutes
- Compatibility: n8n 1.0+, all installation methods (Python requires n8n 0.198+)
- Last updated: March 2026

## TL;DR

The Code node in n8n lets you run JavaScript or Python directly in your workflow. In JavaScript mode, return an array of objects with a json property: return [{json: {key: 'value'}}]. In Python mode, return [{"json": {"key": "value"}}]. The node has two run modes — Run Once for All Items processes everything at once, while Run Once for Each Item runs your code per item.

## How to Use the Code Node in n8n

The Code node is your escape hatch when built-in nodes do not cover your use case. It lets you write custom JavaScript or Python code that runs inside your workflow, with full access to input data from previous nodes and n8n helper functions. Use it for data transformations, custom API logic, calculations, text processing, or any operation that would be awkward to build with standard nodes.

## Before you start

- A running n8n instance with the workflow editor open
- Basic JavaScript or Python programming knowledge
- A workflow with at least one node that produces output data

## Step-by-step guide

### 1. Add a Code node and select the language

Click the plus button to add a new node and search for Code. Add the Code node to your workflow and connect it to the node whose output you want to process. In the Code node settings, select the language — JavaScript or Python. JavaScript is the default and has full access to all n8n helper functions. Python support was added later and has some limitations.

**Expected result:** A Code node is added to your workflow with a code editor panel open. The language selector shows JavaScript or Python.

### 2. Write JavaScript code with correct return format

In JavaScript mode, your code must return an array of objects where each object has a json property containing the output data. Use $input.all() to get all input items or $input.first() to get the first item. Each input item has a json property with the data from the previous node.

```
// JavaScript — basic data transformation
const items = $input.all();

const results = items.map(item => {
  return {
    json: {
      fullName: `${item.json.firstName} ${item.json.lastName}`,
      email: item.json.email.toLowerCase(),
      isActive: item.json.status === 'active',
      processedAt: new Date().toISOString()
    }
  };
});

return results;
```

**Expected result:** The Code node outputs transformed items with the fullName, email, isActive, and processedAt fields visible in the output panel.

### 3. Write Python code with correct return format

In Python mode, the return format is similar — a list of dictionaries, each with a json key. Access input items via the _input variable. Python mode runs in a sandboxed environment and does not support all Python libraries, but standard data processing with built-in types works well.

```
# Python — basic data transformation
items = []

for item in _input.all():
    data = item.json
    items.append({
        "json": {
            "fullName": f"{data['firstName']} {data['lastName']}",
            "email": data["email"].lower(),
            "isActive": data["status"] == "active",
            "wordCount": len(data.get("description", "").split())
        }
    })

return items
```

**Expected result:** The Code node outputs transformed items using Python logic. The output format is identical to JavaScript — downstream nodes receive the same data structure.

### 4. Choose the right run mode

The Code node offers two run modes. 'Run Once for All Items' (default) receives all input items at once and lets you process the entire batch in a single code execution — ideal for aggregations, sorting, or filtering. 'Run Once for Each Item' runs your code once per input item — ideal for per-item transformations where you use $input.item instead of $input.all().

```
// Run Once for All Items mode — aggregate example
const items = $input.all();

const total = items.reduce(
  (sum, item) => sum + item.json.amount,
  0
);

return [{
  json: {
    totalAmount: total,
    itemCount: items.length,
    average: total / items.length
  }
}];

// ---

// Run Once for Each Item mode — per-item example
// $input.item is the current item
const data = $input.item.json;

return [{
  json: {
    ...data,
    taxAmount: data.price * 0.08,
    totalWithTax: data.price * 1.08
  }
}];
```

**Expected result:** In All Items mode, the code runs once and outputs the aggregated result. In Each Item mode, the code runs for each input item and outputs the individually transformed items.

### 5. Access data from other nodes and use helper functions

The Code node can reference output from any node in the workflow using $('NodeName'). You can also access environment variables with $env, workflow static data with $getWorkflowStaticData, and the current execution ID with $execution.id. These helpers make the Code node powerful for complex workflow logic.

```
// Reference another node's output
const webhookData = $('Webhook').first().json;
const apiResponse = $('HTTP Request').all();

// Access environment variables
const apiKey = $env.API_KEY;
const baseUrl = $env.BASE_URL;

// Use static data for persistence between runs
const staticData = $getWorkflowStaticData('global');
staticData.lastRun = new Date().toISOString();

// Get execution metadata
const executionId = $execution.id;
const workflowId = $workflow.id;

return [{
  json: {
    webhookBody: webhookData.body,
    apiItemCount: apiResponse.length,
    environment: baseUrl,
    executionId,
    workflowId
  }
}];
```

**Expected result:** The Code node output contains data pulled from multiple sources including other nodes, environment variables, and execution metadata.

### 6. Handle errors in the Code node

Wrap your code in try-catch blocks to handle errors gracefully instead of crashing the workflow. You can return error information as output items for downstream error handling, or throw an error to stop the workflow when a critical failure occurs. Use the Continue on Error node option for non-critical failures.

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

for (const item of items) {
  try {
    // Process item — may fail for some items
    const parsed = JSON.parse(item.json.rawData);
    results.push({
      json: {
        id: item.json.id,
        parsed,
        status: 'success'
      }
    });
  } catch (error) {
    errors.push({
      json: {
        id: item.json.id,
        error: error.message,
        status: 'failed'
      }
    });
  }
}

// Return both successes and errors
return [...results, ...errors];
```

**Expected result:** Items that process successfully are output with a success status. Items that fail are output with error details instead of crashing the entire workflow.

## Complete code example

File: `code-node-data-transformer.js`

```javascript
// Code Node: Complete data processing pipeline
// Run Mode: Run Once for All Items
//
// This example reads customer data, validates fields,
// enriches with computed properties, and outputs
// clean records plus a summary.

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

// Validation and transformation
for (const item of items) {
  const data = item.json;
  const errors = [];

  // Validate required fields
  if (!data.email || !data.email.includes('@')) {
    errors.push('Invalid or missing email');
  }
  if (!data.name || data.name.trim().length < 2) {
    errors.push('Name is required (min 2 characters)');
  }
  if (typeof data.amount !== 'number' || data.amount < 0) {
    errors.push('Amount must be a positive number');
  }

  if (errors.length > 0) {
    invalidRecords.push({
      json: { ...data, validationErrors: errors, isValid: false }
    });
    continue;
  }

  // Transform valid records
  validRecords.push({
    json: {
      id: data.id,
      name: data.name.trim(),
      email: data.email.toLowerCase().trim(),
      amount: Math.round(data.amount * 100) / 100,
      tax: Math.round(data.amount * 0.08 * 100) / 100,
      total: Math.round(data.amount * 1.08 * 100) / 100,
      category: data.amount > 1000 ? 'premium' : 'standard',
      isValid: true,
      processedAt: new Date().toISOString()
    }
  });
}

// Build summary
const summary = {
  json: {
    _type: 'summary',
    totalInput: items.length,
    validCount: validRecords.length,
    invalidCount: invalidRecords.length,
    totalAmount: validRecords.reduce(
      (sum, r) => sum + r.json.amount, 0
    ),
    processedAt: new Date().toISOString()
  }
};

// Return all records plus summary
return [...validRecords, ...invalidRecords, summary];
```

## Common mistakes

- **Returning objects without the json wrapper: return [{name: 'Alice'}]** — undefined Fix: Every item must have a json property: return [{json: {name: 'Alice'}}]. This is the n8n data format requirement.
- **Using $input.all() in 'Run Once for Each Item' mode** — undefined Fix: In Each Item mode, use $input.item to access the current item. $input.all() is for All Items mode.
- **Forgetting to return a value from the Code node** — undefined Fix: The Code node must always return an array of items. If you have no output, return an empty array: return [].
- **Using require() or import to load external libraries** — undefined Fix: The Code node runs in a sandboxed environment and cannot import external npm packages. Use built-in JavaScript methods or add an npm package to the n8n Docker image if you need it.

## Best practices

- Always return data in the correct format: [{json: {key: 'value'}}] for JavaScript, [{"json": {"key": "value"}}] for Python
- Use 'Run Once for All Items' mode for aggregations, sorting, and filtering entire datasets
- Use 'Run Once for Each Item' mode for simple per-item transformations to keep code clean
- Wrap code in try-catch blocks to handle errors gracefully and prevent workflow crashes
- Reference other nodes by their exact display name — $('Node Name') is case-sensitive
- Keep Code nodes focused on one task — split complex logic into multiple Code nodes for readability
- Use console.log() for debugging — output appears in the browser developer console during manual execution
- Prefer built-in n8n nodes over Code nodes when available — they are easier to maintain and update

## Frequently asked questions

### Can I use external npm packages in the Code node?

No. The Code node runs in a sandboxed environment without access to npm. For simple tasks, use built-in JavaScript. For external libraries, create a custom n8n node or add packages to your Docker image.

### What is the difference between the Code node and the old Function node?

The Code node replaces the deprecated Function and Function Item nodes. It combines both modes (All Items and Each Item) into a single node and adds Python support. Existing Function nodes still work but should be migrated.

### Can I make HTTP requests from the Code node?

Yes. In JavaScript mode, you can use the built-in $http helper or the fetch API (in newer n8n versions). However, using the HTTP Request node is preferred as it handles authentication, retries, and error handling automatically.

### Is Python available in all n8n installations?

Python support requires n8n version 0.198 or later and the Python runtime must be available on the server. Docker installations include Python by default. For npm installations, Python 3 must be installed separately on the host machine.

### How do I debug Code node errors?

Use console.log() statements to inspect data — output appears in your browser developer console during manual execution. You can also add try-catch blocks and return error details as output items for inspection in the n8n UI.

### Can the Code node access the filesystem?

By default, no. The Code node runs in a sandboxed environment for security. If you need file access in self-hosted n8n, you can enable it with the NODE_FUNCTION_ALLOW_EXTERNAL environment variable, but this is not recommended for security reasons.

---

Source: https://www.rapidevelopers.com/n8n-tutorial/how-to-use-the-code-node-in-n8n
© RapidDev — https://www.rapidevelopers.com/n8n-tutorial/how-to-use-the-code-node-in-n8n
