Before you start
The Code node changed a good deal across the 2026 releases, so check your version first. The docs say it replaced the Function and Function Item nodes from n8n 0.198.0. n8n 3.0, in early access since 27 October 2026, removes those legacy nodes. The breaking-changes page maps them across: Run Once for All Items replaces Function and Run Once for Each Item replaces Function Item. The same release removes the Ask AI tab, and code it generated earlier stays and keeps running.
Python moved too. n8n 2.0 removed the Pyodide version, and native Python on task runners arrived in n8n 1.111.0 and is stable as of n8n 2. The samples here are our own, written from the variable names and item shape in the docs.
Write your first Code node
Every item that leaves the node is an object with a json key. The sample below builds new items from the name field of each input item and sets pairedItem, which a later section explains:
// Mode: Run Once for All Items
const rows = $input.all();
const out = [];
for (let i = 0; i < rows.length; i++) {
out.push({
json: { name: rows[i].json.name, nameLength: rows[i].json.name.length },
pairedItem: i,
});
}
return out;- Add a Code node after a node that outputs items with a
namefield, such as an Edit Fields node. - Set Language to JavaScript and Mode to Run Once for All Items, which is the default.
- Paste the sample into the code editor.
- Select Execute step. The output should hold one item per input item, each with
nameandnameLength. - Add
console.log(rows.length)above the return, run the node again and open your browser's developer console. The cookbook page saysconsole.log()in the Code node writes there.
Two modes, two return shapes
n8n passes data between nodes as an array of objects, each wrapping its data in a json key. The data structure page adds that from n8n 0.166.0 the Code node supplies a missing json key and the array wrapper for you, so a plain object works too. Spelling both out keeps your code honest about what it returns.
The JavaScript task runner's source settles what each mode accepts. Run Once for Each Item runs the code once per input item and expects one item back. Returning null skips that item, and n8n sets pairedItem to the current index for you. This is the each-item version of the sample above:
// Mode: Run Once for Each Item
return { json: { name: $json.name, nameLength: $json.name.length } };| Aspect | Run Once for All Items | Run Once for Each Item |
|---|---|---|
| How often the code runs | Once, however many input items arrive | Once for every input item |
| Read input with | $input.all(), $input.first(), $input.last() | $input.item or $json |
| Return | An array of items | One item |
Returning null | No items come out | That item is skipped |
| Item linking | You set pairedItem on new items | n8n sets pairedItem to the current index |
Reading data from the input and from other nodes
The reference page lists what works in the Code node. Type $ in the editor and n8n suggests the rest. Binary data has its own rule: $binary is not available here, so call this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName), which the cookbook page prefers to reaching into items[0].binary.data.data. It is not supported in Python.
One trap sits between the expressions editor and the Code node. The Code node runs plain JavaScript against native Luxon, not n8n's expression engine, and the shortcuts page says what follows.
| Expression | What you get |
|---|---|
$input.all() | Every input item |
$input.first(), $input.last() | The first or last input item |
$input.item | The item being processed |
$json | Shorthand for $input.item.json, available when running once for each item |
$('Node name').all(), .first(), .last() | Items from another node, with optional branchIndex and runIndex arguments |
$('Node name').item | The item in that node that produced the current one |
$('Node name').itemMatching(i) | Use it in place of .item when you trace back from an input item |
$input.context.noItemsLeft | A boolean that exists only with Loop Over Items |
Python in the Code node
Set Language to Python and you get native Python from task runners. The docs call the move from Pyodide a breaking change, so old scripts may need edits. The same sample in native Python:
# Mode: Run Once for All Items, native Python
rows = []
for item in _items:
rows.append({"json": {"name": item["json"]["name"]}})
return rows- Only
_itemsin all-items mode and_itemin each-item mode exist. The other n8n built-in methods and variables are not supported. - Fields need bracket access, as in
item["json"]["my_new_field"]. The dot formitem.json.myNewFieldis not accepted. - On self-hosted n8n, imports work only for standard library and third-party modules that the
n8nio/runnersimage includes and allowlists. On n8n Cloud, no imports are allowed. - Insecure built-ins are denied by default, and
type()is on the list. Useprint(_items)to inspect data instead.
Keep item linking intact
Most nodes link each output item to the input item that produced it, and later nodes follow that chain with $('Node name').item. In the Code node n8n handles linking for a single item. With more than one incoming item you supply it yourself when you add or return new items, by setting pairedItem to the index of the input item. That is why the first sample carried pairedItem: i.
Going back is the job of itemMatching. This is the docs' example, which restores an email address that an Edit Fields node had dropped:
for(let i=0; i<$input.all().length; i++) {
$input.all()[i].json.restoreEmail = $('Customer Datastore (n8n training)').itemMatching(i).json.email;
}
return $input.all();What the Code node cannot do
Task runners execute the code. The docs call them the only isolation layer between user-provided code and n8n, say internal mode is deprecated and point production instances at external mode, with a runners container beside n8n. The self-hosting lesson covers the Docker side.
The timeout changed too. The task runner variables page still lists a default of 300 seconds for N8N_RUNNERS_TASK_TIMEOUT. The breaking changes drop it to 60, so a longer task fails unless you set the variable yourself.
60
seconds a Code node task may run in n8n 3.0 before it fails, down from 300
Source: n8n Docs: v3.0 breaking changes (read November 5, 2026)
2
modules n8n Cloud lets a JavaScript Code node import, crypto and moment
Source: n8n Docs: Code node (read November 4, 2026)
6.6k
GitHub stars on n8n-skills, a set of Claude Code skills with two for the Code node
Source: Romuald Członkowski on GitHub: n8n-skills (read November 5, 2026)
| You want to | What the Code node does | Use instead |
|---|---|---|
| Make an HTTP request | Not available | The HTTP Request node |
| Read or write a file | Not available | The Read/Write Files from Disk node |
| Use a credential | Not available by design, and this.getCredentials() fails | The HTTP Request node, which supports credentials |
| Import an npm module on self-hosted n8n | Blocked until you allow it | NODE_FUNCTION_ALLOW_BUILTIN and NODE_FUNCTION_ALLOW_EXTERNAL, set on the task runners when you use them |
| Import an npm module on n8n Cloud | Not possible | The two modules n8n provides, crypto and moment |
What the maker of n8n-skills and Samir Saci say about Code node languages
Romuald Członkowski, who works at AiAdvisors in Warsaw, built n8n-skills, a set of Claude Code skills for building n8n workflows. Its Python skill gives blunt advice: use JavaScript for 95% of use cases. The reasons it lists match the Python section above. Native Python sees only _items or _item, read as dicts, and the skill calls the import allowlist its critical limitation.
So write Code nodes in JavaScript by default, and keep Python for a self-hosted instance where the module you need is already allowed.
The n8n team shared a post by Samir Saci on X on 2 October 2025, about moving from Python to JavaScript in n8n. Saci, who describes himself as the founder of LogiGreen, used Code nodes for sales analytics and built ABC and Pareto charts. A port like his starts in Run Once for All Items, because a Pareto chart needs every row at once.
Use JavaScript for 95% of use cases
A screenshot of X's own embed of the post, taken on 5 November 2026, with the time in UTC. Select it to open the post on X.
Common mistakes
- "Code doesn't return items properly" and "Code doesn't return an object". The node must return an array of objects that wrap their data in
json. A script that ends without areturn, or returnsundefined, lands here, as the common issues page explains. - "A 'json' property isn't an object". You set
jsonto an array. Put the array inside an object, such as{ json: { rows } }. - "'import' and 'export' may only appear at the top level". The sandbox does not support them, so use
require(), and on a self-hosted install allow the module first. - "Cannot find module". Install the module into your n8n environment, and with Docker extend the official image. Then set
NODE_FUNCTION_ALLOW_BUILTINorNODE_FUNCTION_ALLOW_EXTERNAL. With external task runners, set them in the runners config file instead. - Calling
$getCredentials()orthis.getCredentials(). It fails by design, so move the authenticated call to an HTTP Request node. - Calling
$evaluateExpression(). n8n 3.0 removed it from the JavaScript Code node, and secure-mode runners, the default since n8n 2.0, already fail on it. Evaluate the expression in a field of an earlier node and read the result. - Running the node over huge data. The memory page includes "Avoid using the Code node where possible" in its tips for cutting memory use.
Try it yourself
- Run the all-items sample, then the each-item sample on the same input, and compare the output items.
- In the each-item sample, return
nullfor items with nonameand count how many items come out. - Add
console.log($input.first())and read the browser console while you run the node. - If you self-host, allow one built-in module with
NODE_FUNCTION_ALLOW_BUILTIN=crypto, load it withrequire()and hash a field.
What to learn next
The Code node runs on task runners, and each worker in a scaled setup needs its own. Lesson 4 puts n8n into queue mode, with Redis, workers and the settings that decide how much runs at once. For the bigger picture of what n8n nodes can do before you reach for code, what is n8n is the place to start.
Check yourself
You use Run Once for Each Item. What should the code return?
Show answer
B. One item, such as { json: { ... } } Each-item mode runs the code once per input item and expects one item back, and null skips that item.
The Code node cannot reach credentials. Which node makes an authenticated API call?
Show answer
D. HTTP Request The HTTP Request node supports credentials, which the Code node cannot access by design.
In native Python in the Code node, how do you read the name field of an input item?
Show answer
A. item["json"]["name"] Native Python accepts only bracket access, and the dot form works in the retired Pyodide version.
In Run Once for All Items mode you create new items that later nodes must trace back. What do you set on each?
Show answer
C. pairedItem New items are linked to no input unless you set pairedItem to the index of the input item.
Frequently asked questions
Can the n8n Code node make HTTP requests?
No. The docs say you can't access the file system or make HTTP requests in the Code node. Use the HTTP Request node, which also supports credentials, and the Read/Write Files from Disk node.
Can I use npm packages in the Code node?
On self-hosted n8n, yes: NODE_FUNCTION_ALLOW_BUILTIN takes built-in module names, NODE_FUNCTION_ALLOW_EXTERNAL takes npm packages, and commas separate several names. With external task runners you set them on the runners. On n8n Cloud you cannot import external modules, and only crypto and moment are available.
Can I import Python libraries in the Code node?
Not on n8n Cloud, where the Python option allows no imports at all. Self-hosters can add libraries to the n8nio/runners image and allowlist them, and the docs say the n8n team is committed to allowing arbitrary libraries securely in the long term.
Do old Function nodes still run after upgrading?
No. A workflow that uses a removed node fails when it runs, and a published one does not activate when n8n starts, so its triggers stop firing. Before you upgrade, Settings, then Migration Report, lists the affected workflows.
Why does my Code node complain about json?
Because json holds something other than an object, most often an array. Wrap the array in an object, such as { json: { rows } }. n8n adds a missing json key and the outer array for you, but it cannot fix a json that is itself an array.
How do I debug code in the Code node?
Use console.log() in JavaScript or print() in Python, then open your browser's developer console and run the node. In native Python you can print _items or _item directly.
Sources
- n8n Docs: Code node https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code
- n8n Docs: Using the Code node https://docs.n8n.io/build/code-in-n8n/using-the-code-node
- n8n Docs: Code node common issues https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/common-issues
- n8n Docs: Enable modules in Code node https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/configuration-examples/enable-modules-in-code-node
- n8n Docs: Understand n8n's data structure https://docs.n8n.io/build/work-with-data/understand-n8ns-data-structure
- n8n Docs: Reference previous nodes https://docs.n8n.io/build/work-with-data/reference-data/reference-previous-nodes
- n8n Docs: Use built-in shortcuts https://docs.n8n.io/build/code-in-n8n/use-built-in-shortcuts
- n8n Docs: Output to the browser console https://docs.n8n.io/build/code-in-n8n/cookbook/code-node/output-to-the-browser-console
- n8n Docs: Get the binary data buffer https://docs.n8n.io/build/code-in-n8n/cookbook/code-node/get-the-binary-data-buffer
- n8n Docs: Accessing linked items in the Code node https://docs.n8n.io/build/work-with-data/reference-data/link-data-items/accessing-linked-items-in-the-code-node
- n8n Docs: Preserving linking in the Code node https://docs.n8n.io/build/work-with-data/reference-data/link-data-items/preserving-linking-in-the-code-node
- n8n Docs: Set up task runners https://docs.n8n.io/deploy/host-n8n/configure-n8n/set-up-task-runners
- n8n Docs: Task runner environment variables https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables/task-runners
- n8n Docs: Fix memory issues https://docs.n8n.io/deploy/host-n8n/configure-n8n/scaling/fix-memory-issues
- n8n Docs: v3.0 breaking changes https://docs.n8n.io/changelog/v30-breaking-changes
- n8n repository: JavaScript task runner (js-task-runner.ts) https://github.com/n8n-io/n8n/blob/master/packages/@n8n/task-runner/src/js-task-runner/js-task-runner.ts
- Romuald Członkowski on GitHub: n8n-skills https://github.com/czlonkowski/n8n-skills
- n8n.io on X: great post by Samir Saci on moving from Python to JavaScript in n8n, 2 October 2025 https://x.com/n8n_io/status/1973659279413403874

