Skip to content
New: a free website for your business, live in 48 to 72 hoursWorkflow automation on n8n and Claude, built for your businessFixed price, agreed before we start · Live in 5 to 10 business days30-day money-back guarantee on every planProfessional firms · Agencies · E-commerceYou own every workflow, in your own n8nClaude API: your data is not used for trainingHuman approval on every sensitive stepFree automation audit, no obligation
PURIST
30 days
Money-back window
14 h/wk
Modeled time saved
99.97%
Uptime SLA
< 7 days
Deploy time
PURIST AI
Claude Opus 4.7 · n8n v1.71 · <80ms
What type of business are you running? I'll show you exactly which processes we'd automate first and your estimated ROI.
Powered by n8n + Claude Opus 4.7 Get my free automation plan →
Python in the n8n Code Node (n8n 2.x): Setup, Syntax and Limits
Guides 7 min read · 1,393 words

Python in the n8n Code Node (n8n 2.x): Setup, Syntax and Limits

n8n replaced its Pyodide-based Python with native Python on task runners. What changed, the syntax that works now, how to allow imports when self-hosting, and when JavaScript is still the better choice.

Steve, founder of PURIST

November 6, 2026

PURIST: Stuck on n8n? Our n8n experts fix and build workflows like this one, at a fixed price →

Python in n8n changed significantly. The first implementation ran Python through Pyodide, a WebAssembly port of CPython. n8n then introduced native Python on task runners, available from version 1.111.0 and stable as of n8n 2. Pyodide is removed in n8n 2.0. If your old Python snippets now fail, this is why. Here is how the current version works.

In short. In native Python you read data with _items (Run Once for All Items) or _item (Run Once for Each Item), using bracket notation: item["json"]["email"]. Other n8n helpers such as _input or _now are not supported in native Python. Imports are blocked by default: allow them with N8N_RUNNERS_STDLIB_ALLOW and N8N_RUNNERS_EXTERNAL_ALLOW on self-hosted. On n8n Cloud you cannot import any library.

Python in the n8n Code Node (n8n 2.x): Setup, Syntax and Limits: workflow diagram
Native Python runs on task runners in n8n 2.x, with bracket notation and allow-listed imports. Illustration: PURIST.

What changed from Pyodide to native Python

According to the n8n documentation, the main differences are:

TopicPyodide (legacy)Native Python (current)
AvailabilityRemoved in n8n 2.0From 1.111.0, stable in n8n 2
Data accessMany _ helpers, dot notationOnly _items and _item, bracket notation
LibrariesPackages bundled with PyodideStandard library and third-party, if allowed and installed (self-hosted)
Insecure built-insAllowedDenied by default
SpeedSlower than JavaScriptRuns in a real Python process

Upgrading is a breaking change, so plan to rewrite snippets that used dot access such as item.json.myField.

The syntax that works

Run Once for All Items

python
out = []
for item in _items:
    data = item["json"]
    out.append({"json": {
        "email": str(data.get("email", "")).strip().lower(),
        "company": data.get("company"),
    }})
return out

Run Once for Each Item

python
data = _item["json"]
data["full_name"] = f'{data.get("first_name", "")} {data.get("last_name", "")}'.strip()
return _item

The return format is the same as in JavaScript: a list of dictionaries, each with a "json" key holding a dictionary.

Python in the n8n Code Node (n8n 2.x): Setup, Syntax and Limits: node settings
A per-item Python Code node with an allowed standard-library import. Illustration: PURIST.

Allowing imports on self-hosted n8n

By default native Python blocks all imports, even json or datetime from the standard library. Two variables open them:

VariableWhat it allows
N8N_RUNNERS_STDLIB_ALLOWStandard library modules, for example json,datetime,re, or *
N8N_RUNNERS_EXTERNAL_ALLOWThird-party modules, for example pandas, or *

Third-party packages must also exist in the runner image (n8nio/runners in the official setup). The documentation describes adding extra dependencies by extending that image. In external mode, set these variables in the runners configuration, not on the main n8n container.

python
# With N8N_RUNNERS_STDLIB_ALLOW=re,datetime
import re
from datetime import datetime, timedelta
out = []
for item in _items:
    phone = re.sub(r"[^0-9+]", "", str(item["json"].get("phone", "")))
    follow_up = (datetime.utcnow() + timedelta(days=3)).strftime("%Y-%m-%d")
    out.append({"json": {**item["json"], "phone": phone, "follow_up": follow_up}})
return out

n8n Cloud

On n8n Cloud the Python option of the Code node does not allow importing any library, from the standard library or third parties. Plain Python works; import does not. If you need a library on Cloud, use JavaScript (which has crypto and moment), a dedicated n8n node, or call an external function with the HTTP Request node.

Python or JavaScript?

Choose JavaScript when:

  • you need n8n helpers such as $('Node name'), $execution, $now or binary data functions, which native Python does not support;
  • you are on n8n Cloud and need any library;
  • the next person maintaining the workflow does not read Python.

Choose Python when the logic itself is easier in Python (text processing, data science libraries you are allowed to install) and the input arrives through the node's own items.

Worked example: migrate a Pyodide snippet to native Python

Many workflows built in 2023 and 2024 contain snippets like this one, which stopped working when Pyodide was removed:

python
# Old (Pyodide), no longer supported
for item in _input.all():
    item.json.email = item.json.email.lower().strip()
    item.json.domain = item.json.email.split("@")[1]
return _input.all()

The native version, for "Run Once for All Items":

python
out = []
for item in _items:
    d = dict(item["json"])
    email = str(d.get("email", "")).strip().lower()
    d["email"] = email
    d["domain"] = email.split("@")[1] if "@" in email else None
    out.append({"json": d})
return out

What changed, line by line:

  • _input.all() became _items;
  • item.json.email became item["json"]["email"], read safely with .get();
  • the item is rebuilt as a dictionary with a "json" key before returning;
  • the domain split is guarded, because native Python raises an error on a missing @ just like the old code did, but now you see it instead of a vague failure.

Allowing libraries on self-hosted n8n

Three steps, in this order:

  1. 1 Install third-party packages in the runner image (the official runner image is n8nio/runners), by extending it as the n8n documentation describes.
  2. 2 Allow them: standard-library modules in N8N_RUNNERS_STDLIB_ALLOW, third-party modules in N8N_RUNNERS_EXTERNAL_ALLOW. Use names, not *, unless the instance is single-user.
  3. 3 Restart the runners.

There is also N8N_RUNNERS_ALLOW_TRANSITIVE_IMPORTS: by default, imports made inside an allowed package must be allowed too. Turning it on lets an allowed package load its own dependencies, at the cost of a wider surface.

When native Python is the right tool

JobPython fit
Text cleanup with regular expressionsGood, with re allowed
Statistics on a list of numbersGood, with statistics allowed
Heavy data work (pandas) on self-hostedPossible if installed and allowed in the runner
Reading other nodes, $now, execution dataNot supported in native Python: use JavaScript
Files and binary dataNot supported: use JavaScript or file nodes
n8n Cloud with any importNot possible

Troubleshooting table

SymptomLikely causeFix
NameError: _input is not definedPyodide-era helperUse _items or _item
AttributeError: 'dict' object has no attribute 'json'Dot notationUse item["json"]
Import blockedModule not in the allow listAdd it to N8N_RUNNERS_STDLIB_ALLOW or _EXTERNAL_ALLOW
ModuleNotFoundError for a third-party packageNot installed in the runner imageExtend the runner image
Any import on n8n CloudNot supportedUse plain Python or JavaScript
Script stopped after a few minutesRunner task timeout (300 s by default)Split the work or raise N8N_RUNNERS_TASK_TIMEOUT

Production checklist

  • n8n version checked: native Python, not Pyodide, from n8n 2.0.
  • Bracket notation everywhere (item["json"]["field"]).
  • Imports allowed explicitly and installed in the runner image (self-hosted).
  • JavaScript chosen instead when you need n8n helpers or Cloud libraries.

Frequently asked questions

Why did my Python Code node break after upgrading n8n?

n8n 2.0 removed Pyodide. Native Python uses bracket notation (item["json"]["field"]) and only supports _items and _item. Rewrite dot access and remove other _ helpers.

How do I import a Python library in n8n?

On self-hosted n8n, list it in N8N_RUNNERS_STDLIB_ALLOW (standard library) or N8N_RUNNERS_EXTERNAL_ALLOW (third-party), and make sure third-party packages are installed in the runner image. On n8n Cloud, imports are not allowed.

Can I read binary files with Python in n8n?

The getBinaryDataBuffer() helper is not supported in Python. Use JavaScript or the Extract from File node for that step.

Is Python slower than JavaScript in n8n?

The old Pyodide version was noticeably slower. Native Python runs in a real Python process on task runners. For typical workflow volumes either language is fast enough; pick the one your team maintains best.

Is Python faster or slower than JavaScript in n8n?

For typical workflow volumes both are fast. JavaScript has the advantage of n8n's built-in helpers; Python is worth it when the logic or library is genuinely better in Python.

Can I use pandas in n8n?

On self-hosted n8n with native Python, if pandas is installed in the runner image and allowed with N8N_RUNNERS_EXTERNAL_ALLOW. Not on n8n Cloud.

Which n8n version do I need for native Python?

Native Python on task runners is available from n8n 1.111.0 and stable as of n8n 2. Pyodide is removed from n8n 2.0.

Tags

n8npythoncode nodetask runnersself-hosted
Steve, founder of PURIST

Steve founded PURIST, a workflow automation studio working with n8n, Make and Claude AI, and is the point of contact on every project. Prices and features in our articles come from vendor documentation and public pricing pages. How we research and score tools.

Complete guide

Automation Tools & Platforms

11 min read n8n Code Node: 15 JavaScript Examples You Can Copy and … 8 min read n8n Code Node With Multiple Inputs: 3 Methods That Work 7 min read Fix "Cannot find module" in the n8n Code Node (npm Pack… 7 min read n8n Code Node Errors Fixed: "Code doesn't return items … 7 min read $env and Credentials in the n8n Code Node: What Works a… 7 min read n8n Code Node Binary Data: Read, Change and Return File… 7 min read Fix n8n "The requested webhook is not registered" (Test… 6 min read n8n Webhook URL: Test vs Production, and How to Change … 7 min read n8n Respond to Webhook: Return JSON, Status Codes, Redi… 8 min read Secure an n8n Webhook: Header Auth, Basic Auth, JWT and… 7 min read n8n Webhook Not Working? 10 Causes and How to Fix Each … 7 min read n8n HTTP Request Pagination: Every Pattern With Working… 7 min read n8n HTTP Request Authentication: API Keys, Bearer Token… 7 min read n8n HTTP Request Timeout and "Aborted" Errors: Causes a… 7 min read Upload and Download Files With the n8n HTTP Request Nod… 6 min read Fix ECONNREFUSED in n8n: Docker, localhost and 127.0.0.… 6 min read n8n 429 Too Many Requests: Batching, Retries and Rate L… 6 min read Fix redirect_uri_mismatch for n8n OAuth2 Credentials (G… 7 min read n8n Expression Errors Fixed: "Referenced node is unexec… 6 min read Anatomy Claude skill: what it is, how to install it, an… 5 min read How to explain a business process with the Anatomy skil… 5 min read Anatomy vs Mermaid vs Excalidraw: which to explain a wo… 14 min read n8n LinkedIn Job Automation: Auto-Apply, Track, and Fol… 16 min read n8n HTTP Request Node: Complete Documentation and Examp… 18 min read The future of automation: how our engineering team is s… 8 min read n8n vs Make vs Zapier: the honest comparison your busin… 11 min read n8n vs Make vs Zapier: an honest comparison for product… 7 min read Webhook vs polling: the architecture decision that dete… 24 min read n8n tutorial: build your first production workflow in u… 26 min read The 9 best Zapier alternatives in 2026: an honest ranki… 21 min read Make.com tutorial: build powerful automations without c… 19 min read Automation consultant vs DIY: how to decide what is rig… 14 min read n8n Self-Hosted vs Cloud: The Complete Decision Guide (… 15 min read 5 Zapier Free Alternatives That Handle Real Production … 15 min read WhatsApp Business Automation With n8n: Build a 24/7 Cus… 17 min read Google Workspace Automation: 15 Workflows for Sheets, D… 16 min read Claude AI for Business Automation: What It Does, What I… 15 min read Airtable Automation With n8n: 10 Workflows That Make Yo… 15 min read Droven.io AI Automation Tools: Full Review and Best Alt… 14 min read Droven.io RPA and Business Automation: An Honest 2026 R… 15 min read Enterprise Workflow Automation: The Complete Guide for … 13 min read Document Workflow Automation: Software, Implementation,… 14 min read Marketing Automation Workflow: From Content Creation to… 16 min read Ad Campaign Workflow Data Model and SDR Inbound Pipelin… 14 min read ComfyUI Workflows for Business: Product Photography, Ma… 13 min read GPT-5.2 for Business Workflows and the spec-workflow-mc… 17 min read ServiceNow vs IBM BAW vs n8n: Enterprise Workflow Autom… 16 min read 9 Best Workflow Automation Tools for Small Business in …

Keep reading

More from the blog.

All articles

From audit to deployment

Experience the automation
these articles are about.

Get my free automation plan →