n8n Code Node: JavaScript & Python Transformation Examples
⚡ n8n Workflow Automation T3 · Code Node Transformations
n8n Code Node: JavaScript & Python Transformation Examples

The Code node executes custom JavaScript (Node.js 18) or Python (3.10+ native, or legacy Pyodide) as a workflow step, providing full access to incoming data for complex manipulation beyond built‑in nodes. JavaScript runs natively with promises, console.log, and external npm module support; Python runs in a sandboxed subprocess or via WebAssembly depending on n8n version. Both languages share two execution modes—Run Once for All Items (aggregation) and Run Once for Each Item (per‑item mapping)—and must return an array of objects each containing a json key [1].

Node.js 18
JavaScript Runtime [2]
3.10+
Python (Native) Version [3]
2
Execution Modes [1]
1.63.0
Native Python Introduced [3]
Property JavaScript Python (Native) Python (Legacy Pyodide)
Runtime Node.js 18 Native Python 3.10+ Pyodide (CPython via WebAssembly)
Available in Cloud ✅ Yes ❌ No ⚠️ Limited – no external libraries
External Modules Via NODE_FUNCTION_ALLOW_EXTERNAL Full pip (self‑hosted) Pre‑installed Pyodide packages only
Performance Fast (~0.68 ms/exec) Fast (~0.68 ms/exec) Slower (~25.5 ms/exec)
async/await ✅ Yes ✅ Yes ❌ Not supported
Data Access $input.all(), $json _input.all(), _json _input.all(), _json

What are the two Code node execution modes and how do you choose between them?

The Code node provides two execution modes. Run Once for All Items (default) executes code once regardless of input count, accessing all items via $input.all() as an array—ideal for aggregation, counting, cross‑item comparisons, or restructuring nested arrays. Run Once for Each Item executes separately per item, accessing data through $input.item.json (shorthand: $json)—best for independent field mapping and enrichment. [1] [3]

A common mistake: using “Each Item” mode for aggregation tasks like counting total records—each item sees only its own data and cannot compute a sum across all items. Use “All Items” mode when the result depends on multiple items. From n8n 0.166.0, the return format is auto‑corrected if missing the json wrapper—but for maximum compatibility, always explicitly return [{ json: { key: "value" } }]. For production environments, n8n 2.0+ runs Code nodes in isolated Task Runners by default, with process.env access blocked and ExecuteCommand/ LocalFileTrigger nodes disabled [4]. The “Try to avoid the Code node unless you really need it” community benchmark found that Code nodes performing filtering or mapping typically take 1‑3 seconds to execute, compared to near‑instant built‑in nodes—use expressions or Set/IF/Merge nodes when they suffice [5]. For the complete reference of core nodes you can combine with the Code node, see the Core n8n Nodes guide.

How do you iterate over items and transform JSON data with JavaScript in the Code node?

In “Run Once for All Items” mode, loop over all input items with for (const item of $input.all()) { item.json.newField = 1; } return $input.all();. Use the $input.all() array with .map(), .filter(), and .reduce() for functional transformations. To extract a nested array buried inside a JSON wrapper and convert it into n8n’s item structure, use: return $input.first().json.data.map(item => ({ json: item })). [6] [7]

Key data access patterns: $input.all() returns all items as an array; $input.first() returns the first item; $input.last() returns the last; $input.item.json.fieldName accesses the current item’s JSON (available in “Each Item” mode); and $json is shorthand for $input.item.json in “Each Item” mode. Always access item.json.fieldName rather than item.fieldName—the data lives under .json. For async operations, use await $http.get('https://api.example.com') in JavaScript. For complete Code node transformation patterns including flatMap expansion of nested arrays into individual items, Luxon date formatting, and AJV JSON Schema validation, see the n8n Expression Node reference.

How do you write Python code in the n8n Code node for data transformation?

Python in the Code node accesses items through _input.all() (mirroring $input.all()) and returns the transformed list with return _input.all(). List comprehension enables compact field extraction: summaries = [item.json.get("summary") for item in _input.all()]; return [{"json": {"merged_summary": " ".join(summaries)}}]. In native Python mode (1.63.0+), full Python 3.10+ standard libraries are available; in legacy Pyodide mode, only Pyodide’s built‑in package set works. [8] [9]

A critical Pyodide‑specific pitfall: when type() outputs <class 'pyodide.ffi.JsProxy'>, convert to a native Python object using to_py(). This occurs when working with n8n node data structures such as inputs and outputs. json.dumps() is not compatible with Pyodide JsProxy objects and causes workflow hangs [9]. On n8n Cloud, the Python option for the Code node does not support importing any Python libraries—whether from the standard library or third‑party packages [10]. For the complete comparison of Code node vs Execute Command node—when you need full Python capabilities with pip packages—see the n8n Node Configuration Hub.

🐍 Native Python Upgrade Note (n8n ≥ 1.63.0): Native Python execution replaced legacy Pyodide. All Code nodes created after this version use native Python by default. Existing Pyodide nodes continue to work but receive no further updates. Native Python runs in a sandboxed subprocess and requires the n8n-python package installed on the host [3].

How do you handle dates, external modules, and advanced data structures in the Code node?

Dates: In JavaScript, n8n provides the Luxon library globally— access it with DateTime without any import statement (DateTime.now().toISO()). In native Python, use from datetime import datetime and datetime.fromtimestamp(timestamp).isoformat(). External modules: Self‑hosted JavaScript can import built‑in modules (NODE_FUNCTION_ALLOW_BUILTIN=*) and external npm modules (NODE_FUNCTION_ALLOW_EXTERNAL=axios,moment,lodash) [11].

Binary data: Access binary files via $input.item.binary.fileName in JavaScript or _input.item.binary.fileName in Python. The Code node can generate binary output (PDFs, images) using Buffer operations in JavaScript or bytes() in native Python. Nested arrays to individual items: Use flatMap to expand nested structures: return $input.first().json.items.flatMap(item => ({ json: item })). For the n8n 2.0+ environment, process.env access is blocked by default inside Code nodes—pass variables via $env.VARIABLE_NAME in a Set node before the Code node to keep separation of concerns [11]. For comprehensive error handling, logging, and production‑ready patterns that combine all data structures, see the Core n8n Nodes guide.

How can JavaScript and Python in the Code node be compared for choosing the right tool?

Benchmark data reveals a stark performance gap. In legacy Pyodide mode, Python averages ~25.5 ms per execution compared to ~0.68 ms for JavaScript due to WebAssembly compilation overhead. Native Python (1.63.0+) closes this gap significantly. Beyond raw speed, a single Code node with JavaScript can replace approximately 15 standard nodes for complex logic, reducing execution overhead for enterprise‑grade automations. [12] [8]

The pragmatic decision rule: use JavaScript for performance‑ critical production workflows with npm dependencies and async API calls. Use native Python for data‑science tasks requiring pandas, numpy, or scikit‑learn in self‑hosted deployments. Use Pyodide Python only for lightweight math/string transformations where no external libraries are needed and async is not required. The community best‑practice guide “Try to avoid the Code node unless you really need it” advises: reach for built‑in nodes first, expressions next, and Code node last—since built‑in nodes are more readable, upgrade‑safe, and break less across versions [5]. For the complete expressions reference and the 58+ built‑in methods that can replace Code node logic, see the n8n Expression Node reference.

What are the most common Code node errors and how do you fix them?

Error “A ‘json’ property isn’t an object”—most frequent— occurs when the Code node returns data without wrapping it in the item structure { json: { ... } }. Always return return [{ json: { key: "value" } }]. Error workflow hangs in Python—caused by json.dumps() on Pyodide JsProxy objects; convert with to_py() first. [13] [14]

Error Code node times out—default timeout is 300 seconds; increase via node Settings or set EXECUTIONS_TIMEOUT environment variable. Error Python module import fails—on n8n Cloud, no Python libraries are importable; on self‑hosted, verify the module is installed and accessible. Error process.env undefined in n8n 2.0+—Code nodes can no longer access environment variables directly; pass values via $env in nodes upstream of the Code node. For systematic debugging strategies that catch these errors at runtime, see the n8n Error Handling nodes guide.

🧵 Data Structure Golden Rule: Every Code node, in every language, in every execution mode, must return an array of objects each containing a json key. For a single output: return [{ json: { key: "value" } }]. For multiple outputs: return [{ json: { id: 1 } }, { json: { id: 2 } }]. The json value must be a plain object—not an array, not a string, not a number [13].
Error Message Likely Cause Fix
“A ‘json’ property isn’t an object” Returned array of raw values ([1, 2, 3]) instead of item objects Wrap each value: [{ json: { value: 1 } }, ...]
Workflow hangs (Python) json.dumps() on Pyodide JsProxy object Call .to_py() first, then json.dumps()
“process is not defined” (n8n 2.0+) Accessing process.env in Code node (blocked by default) Pass env values via Set node using $env.VARIABLE
“ExpressionError” / timeout Code execution exceeds 300s default timeout Set EXECUTIONS_TIMEOUT env var or node‑level timeout

References

This guide is for informational purposes only. For the most current and authoritative information, always refer to the official n8n website (n8n.io) and the n8n documentation. Node parameters, Python version support, and execution defaults may change over time.

Leave a Reply

Your email address will not be published. Required fields are marked *