Skip to main content
RapidDev - Software Development Agency
n8n-tutorial

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

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.

What you'll learn

  • How to write JavaScript and Python code in the Code node with correct input/output format
  • How to choose between Run Once for All Items and Run Once for Each Item modes
  • How to access input data, reference other nodes, and use n8n helper functions
  • How to handle errors and debug Code node logic
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read15-20 minutesn8n 1.0+, all installation methods (Python requires n8n 0.198+)March 2026RapidDev Engineering Team
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.

Prerequisites

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

typescript
1// JavaScript — basic data transformation
2const items = $input.all();
3
4const results = items.map(item => {
5 return {
6 json: {
7 fullName: `${item.json.firstName} ${item.json.lastName}`,
8 email: item.json.email.toLowerCase(),
9 isActive: item.json.status === 'active',
10 processedAt: new Date().toISOString()
11 }
12 };
13});
14
15return 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.

typescript
1# Python basic data transformation
2items = []
3
4for item in _input.all():
5 data = item.json
6 items.append({
7 "json": {
8 "fullName": f"{data['firstName']} {data['lastName']}",
9 "email": data["email"].lower(),
10 "isActive": data["status"] == "active",
11 "wordCount": len(data.get("description", "").split())
12 }
13 })
14
15return 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().

typescript
1// Run Once for All Items mode — aggregate example
2const items = $input.all();
3
4const total = items.reduce(
5 (sum, item) => sum + item.json.amount,
6 0
7);
8
9return [{
10 json: {
11 totalAmount: total,
12 itemCount: items.length,
13 average: total / items.length
14 }
15}];
16
17// ---
18
19// Run Once for Each Item mode — per-item example
20// $input.item is the current item
21const data = $input.item.json;
22
23return [{
24 json: {
25 ...data,
26 taxAmount: data.price * 0.08,
27 totalWithTax: data.price * 1.08
28 }
29}];

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.

typescript
1// Reference another node's output
2const webhookData = $('Webhook').first().json;
3const apiResponse = $('HTTP Request').all();
4
5// Access environment variables
6const apiKey = $env.API_KEY;
7const baseUrl = $env.BASE_URL;
8
9// Use static data for persistence between runs
10const staticData = $getWorkflowStaticData('global');
11staticData.lastRun = new Date().toISOString();
12
13// Get execution metadata
14const executionId = $execution.id;
15const workflowId = $workflow.id;
16
17return [{
18 json: {
19 webhookBody: webhookData.body,
20 apiItemCount: apiResponse.length,
21 environment: baseUrl,
22 executionId,
23 workflowId
24 }
25}];

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.

typescript
1const items = $input.all();
2const results = [];
3const errors = [];
4
5for (const item of items) {
6 try {
7 // Process item — may fail for some items
8 const parsed = JSON.parse(item.json.rawData);
9 results.push({
10 json: {
11 id: item.json.id,
12 parsed,
13 status: 'success'
14 }
15 });
16 } catch (error) {
17 errors.push({
18 json: {
19 id: item.json.id,
20 error: error.message,
21 status: 'failed'
22 }
23 });
24 }
25}
26
27// Return both successes and errors
28return [...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 working example

code-node-data-transformer.js
1// Code Node: Complete data processing pipeline
2// Run Mode: Run Once for All Items
3//
4// This example reads customer data, validates fields,
5// enriches with computed properties, and outputs
6// clean records plus a summary.
7
8const items = $input.all();
9const validRecords = [];
10const invalidRecords = [];
11
12// Validation and transformation
13for (const item of items) {
14 const data = item.json;
15 const errors = [];
16
17 // Validate required fields
18 if (!data.email || !data.email.includes('@')) {
19 errors.push('Invalid or missing email');
20 }
21 if (!data.name || data.name.trim().length < 2) {
22 errors.push('Name is required (min 2 characters)');
23 }
24 if (typeof data.amount !== 'number' || data.amount < 0) {
25 errors.push('Amount must be a positive number');
26 }
27
28 if (errors.length > 0) {
29 invalidRecords.push({
30 json: { ...data, validationErrors: errors, isValid: false }
31 });
32 continue;
33 }
34
35 // Transform valid records
36 validRecords.push({
37 json: {
38 id: data.id,
39 name: data.name.trim(),
40 email: data.email.toLowerCase().trim(),
41 amount: Math.round(data.amount * 100) / 100,
42 tax: Math.round(data.amount * 0.08 * 100) / 100,
43 total: Math.round(data.amount * 1.08 * 100) / 100,
44 category: data.amount > 1000 ? 'premium' : 'standard',
45 isValid: true,
46 processedAt: new Date().toISOString()
47 }
48 });
49}
50
51// Build summary
52const summary = {
53 json: {
54 _type: 'summary',
55 totalInput: items.length,
56 validCount: validRecords.length,
57 invalidCount: invalidRecords.length,
58 totalAmount: validRecords.reduce(
59 (sum, r) => sum + r.json.amount, 0
60 ),
61 processedAt: new Date().toISOString()
62 }
63};
64
65// Return all records plus summary
66return [...validRecords, ...invalidRecords, summary];

Common mistakes when using the Code Node in n8n for Custom JavaScript and Python

Why it's a problem: Returning objects without the json wrapper: return [{name: 'Alice'}]

How to avoid: Every item must have a json property: return [{json: {name: 'Alice'}}]. This is the n8n data format requirement.

Why it's a problem: Using $input.all() in 'Run Once for Each Item' mode

How to avoid: In Each Item mode, use $input.item to access the current item. $input.all() is for All Items mode.

Why it's a problem: Forgetting to return a value from the Code node

How to avoid: The Code node must always return an array of items. If you have no output, return an empty array: return [].

Why it's a problem: Using require() or import to load external libraries

How to avoid: 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

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I need to write an n8n Code node that takes an array of order items, validates that each has a valid email and positive amount, calculates tax at 8%, and returns both valid and invalid items separately. Show me the JavaScript code with proper n8n return format.

n8n Prompt

Write a Code node in JavaScript that reads input items, groups them by the 'category' field, and outputs one item per category with the count and total amount for that category.

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.