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
Add a Code node and select the language
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.
Write JavaScript code with correct return format
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.
1// JavaScript — basic data transformation2const items = $input.all();34const 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});1415return results;Expected result: The Code node outputs transformed items with the fullName, email, isActive, and processedAt fields visible in the output panel.
Write Python code with correct return format
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.
1# Python — basic data transformation2items = []34for item in _input.all():5 data = item.json6 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 })1415return itemsExpected result: The Code node outputs transformed items using Python logic. The output format is identical to JavaScript — downstream nodes receive the same data structure.
Choose the right run mode
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().
1// Run Once for All Items mode — aggregate example2const items = $input.all();34const total = items.reduce(5 (sum, item) => sum + item.json.amount,6 07);89return [{10 json: {11 totalAmount: total,12 itemCount: items.length,13 average: total / items.length14 }15}];1617// ---1819// Run Once for Each Item mode — per-item example20// $input.item is the current item21const data = $input.item.json;2223return [{24 json: {25 ...data,26 taxAmount: data.price * 0.08,27 totalWithTax: data.price * 1.0828 }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.
Access data from other nodes and use helper functions
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.
1// Reference another node's output2const webhookData = $('Webhook').first().json;3const apiResponse = $('HTTP Request').all();45// Access environment variables6const apiKey = $env.API_KEY;7const baseUrl = $env.BASE_URL;89// Use static data for persistence between runs10const staticData = $getWorkflowStaticData('global');11staticData.lastRun = new Date().toISOString();1213// Get execution metadata14const executionId = $execution.id;15const workflowId = $workflow.id;1617return [{18 json: {19 webhookBody: webhookData.body,20 apiItemCount: apiResponse.length,21 environment: baseUrl,22 executionId,23 workflowId24 }25}];Expected result: The Code node output contains data pulled from multiple sources including other nodes, environment variables, and execution metadata.
Handle errors in the Code node
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.
1const items = $input.all();2const results = [];3const errors = [];45for (const item of items) {6 try {7 // Process item — may fail for some items8 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}2627// Return both successes and errors28return [...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
1// Code Node: Complete data processing pipeline2// Run Mode: Run Once for All Items3//4// This example reads customer data, validates fields,5// enriches with computed properties, and outputs6// clean records plus a summary.78const items = $input.all();9const validRecords = [];10const invalidRecords = [];1112// Validation and transformation13for (const item of items) {14 const data = item.json;15 const errors = [];1617 // Validate required fields18 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 }2728 if (errors.length > 0) {29 invalidRecords.push({30 json: { ...data, validationErrors: errors, isValid: false }31 });32 continue;33 }3435 // Transform valid records36 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}5051// Build summary52const 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, 060 ),61 processedAt: new Date().toISOString()62 }63};6465// Return all records plus summary66return [...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.
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.
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation