n8n Code node: Python or JavaScript? A decision guide for builders

6 min read

TL;DR

  • When you n8n execute python code in the Code node, the runtime is Pyodide (CPython 3.11 on WebAssembly), not a system Python interpreter.
  • No pip at runtime: roughly 250 packages are bundled (numpy and pandas yes, torch and scikit-learn no).
  • JavaScript handles JSON-heavy item manipulation with less friction; Python wins on numeric computation.
  • For full PyPI access, use the Execute Command node (self-hosted only) or a FastAPI sidecar (works on n8n Cloud).
  • As of early 2026, no native Python executor with real pip support is on the public n8n roadmap.

The first time you try to n8n execute python code and import requests inside the Code node, the workflow fails with a module error. That failure is not a bug (it is a precise boundary). The Code node does not run the Python installed on your machine or server. It runs Pyodide, a WebAssembly port of CPython, sandboxed inside the n8n process itself. Understanding that boundary takes five minutes and saves hours of confused debugging. This article maps the exact capabilities of both language options in the Code node, gives you a decision matrix for common builder use cases, and documents the two escape hatches when neither language covers the ground you need.

What the Code node actually runs when you n8n execute python code

Since n8n v1.0 (July 2023), the Code node has offered Python as an alternative to JavaScript. The runtime is Pyodide, a port of CPython 3.11 compiled to WebAssembly. The code executes inside the n8n process. There is no separate Python binary involved, no virtual environment, no PATH lookup.

That architecture creates hard sandbox limits:

  • No pip install at runtime. Pyodide ships a fixed package list compiled for WebAssembly. You can call micropip.install() for pure-Python packages on PyPI, but compiled C or Fortran extensions only work if a WebAssembly build is included in the Pyodide distribution itself.
  • No subprocess or os.system. The WebAssembly sandbox blocks all OS-level calls. You cannot spawn processes, open arbitrary file paths, or create raw TCP sockets.
  • No host filesystem access. File operations are limited to an in-memory virtual filesystem that disappears when the execution ends.

The practical result: roughly 250 packages are available out of the box, compared to 500,000 on full PyPI. The bundled list covers scientific computing well (numpy, pandas, scipy) but excludes most ML inference frameworks and HTTP client libraries. Torch is not available. scikit-learn is not available. requests is not available (you can use the Pyodide JavaScript fetch bridge instead, but it requires async boilerplate).

Data enters and exits your Python code as items (a list of dictionaries that mirrors the n8n item format). Serialization passes through a JSON bridge, which means datetime objects and custom class instances need explicit conversion before you return them.

JavaScript in the Code node: what it does that Python cannot

The JavaScript side of the Code node runs on Node.js. n8n 1.x shipped with Node.js 18 LTS, which reached end-of-life in October 2025. Late 2025 releases of n8n migrated to Node.js 20 LTS, extending security support well into 2026.

The sandbox restrictions are the same as Pyodide: no npm install at runtime, no subprocess, no arbitrary filesystem access. The meaningful difference is ergonomic.

JavaScript is the native language of the n8n data model. The items array and every node output are plain JSON objects. Transforming, filtering, and reshaping them in JavaScript requires no serialization step (you work directly with the structures n8n already uses internally). The same operation in Python goes through the Pyodide object bridge, which adds friction and occasional type-coercion surprises. JavaScript null becomes Python None reliably, but undefined has no direct equivalent, and numeric precision can differ.

JavaScript also gets first-class access to n8n's built-in context helpers: $json, $node, $workflow, $execution, and the Luxon date library are all available without any import. For date arithmetic inside workflow scripting tasks, Luxon handles timezone-aware operations cleanly with no additional setup.

For code automation that touches API responses, reshapes pagination, or filters arrays of records, JavaScript is the lower-friction choice in the Code node.

Python vs JavaScript in the Code node: decision matrix

The table below maps common builder use cases to the recommended language with a feasibility rating.

Use caseRecommendedFeasibilityNotes
JSON / item transformationJavaScriptHighNo serialization overhead
Regex text processingEitherHighBoth runtimes handle well
Numeric computationPythonHighnumpy, scipy bundled in Pyodide
Pandas data wranglingPythonHighpandas 2.x available; large frames are slow
ML inferenceNeitherBlockedtorch, scikit-learn absent from Pyodide
HTTP requests to external APIsJavaScriptHighUse $http helper or fetch
Date and time arithmeticJavaScriptHighLuxon available without import
Base64 and encoding utilitiesEitherHighBoth runtimes cover this well
Custom class serializationJavaScriptMediumPython class objects need manual conversion
Workflow scripting with pip depsExternal runnerN/AExit the Code node entirely

When you need to run Python scripts that rely on numpy or pandas for lightweight aggregation or unit conversion, the Code node is a legitimate option. When the task requires torch, requests, or anything depending on compiled C extensions not yet ported to WebAssembly, the Code node is a dead end regardless of which language you pick.

Two escape hatches when the Code node is not enough

Execute Command node: self-hosted only, full Python

The Execute Command node lets n8n call any shell command on the host. On a self-hosted instance with Python 3 installed, you invoke python3 script.py with full PyPI access via pip. Your Python in workflows runs in a real interpreter with no Pyodide constraints.

Overhead is under 50 ms per call for a warm process. The trade-off: Execute Command is disabled on n8n Cloud. If you migrate away from self-hosted, these workflows break.

Use this for Python automation tasks with heavy pip dependencies where you control the infrastructure and do not plan to move to managed hosting.

FastAPI sidecar: the cloud-compatible path

Run a small FastAPI application in a Docker container alongside n8n, expose it on a local port, and call it from the n8n HTTP Request node. Your scripts run inside a real CPython interpreter with the full package ecosystem available.

A warm FastAPI container answers in under 5 ms for lightweight computation. Cold start on a freshly launched container lands around 80 ms. This pattern works on n8n Cloud because the HTTP Request node can call any reachable endpoint, including localhost or a sidecar on a private network.

Separating Python execution from the n8n process also makes the code independently testable and deployable. That's a meaningful operational advantage as workflow scripting complexity grows.

Pyodide package availability in 2026 and what the roadmap signals

Pyodide 0.26, released in late 2024, added CPython 3.12 support and expanded the package list. As of early 2026, the distribution includes over 250 packages compiled for WebAssembly, with updated numpy, pandas 2.x, and scipy 1.13 among the additions most relevant to n8n builders.

What remains absent has not changed materially: torch, scikit-learn, requests, httpx, and any package depending on compiled C extensions not ported to WebAssembly. The micropip escape hatch helps for pure-Python packages, but the ceiling on C-extension libraries is structural, not a packaging oversight.

Open issues on the n8n GitHub repository as of early 2026 request a native Python executor that would call a real system Python binary from the Code node, with proper item passing and credential access. No timeline has been announced. The Execute Command node remains the documented workaround for full-PyPI workloads on self-hosted deployments.

For builders choosing a stack today, the practical consequence is clear: Python in the Code node is useful and incrementally improving, but the Pyodide sandbox ceiling is not disappearing in the near term. If your Python automation needs are likely to grow toward ML or complex pip dependencies, design the escape hatch into your architecture from the start rather than retrofitting later. Maybe I'm wrong, but I don't see n8n breaking out of the WebAssembly constraint anytime soon.

Key takeaways

When you n8n execute python code in the Code node, you are running Pyodide, not system Python. Use Python for numeric computation with numpy and pandas. Use JavaScript for JSON-heavy item manipulation, date handling, and direct API response shaping. For any workflow scripting task requiring real pip dependencies, exit the Code node via Execute Command (self-hosted, full PyPI, under 50 ms overhead) or a FastAPI sidecar (cloud-compatible, warm responses under 5 ms). Design with that three-tier decision in mind from the start.


When you hit a module error trying to import requests in n8n's Python Code node, it's not a bug—it's Pyodide (WebAssembly CPython) hitting its sandbox boundary. The CLI Blueprint in the welcome kit shows how to structure escape hatches like FastAPI sidecars that give you full PyPI access without abandoning n8n.

Get the welcome kit