Code node runtime
Exact languages, packages, filesystem, and isolation available to code@1.0.0.
Code nodes run in an immutable BlitFlow Sandbox. Choose runtime: "node" or
runtime: "python"; the runtime decides the source contract and installed
packages. This page is the authoritative list of what each environment
contains — packages from your own application are not available inside a
Sandbox.
Runtime matrix
| Capability | Node | Python |
|---|---|---|
| API | blitflow.code/v1 | blitflow.code/v1 |
| Workflow node | code@1.0.0 | code@1.0.0 |
| Supported versions | 1, 2 | 1 |
| Authoring default | 2 | 1 |
| Python environment | — | 1 |
| Language | JavaScript | Python |
| Module format | ECMAScript module (ESM) | Python source module |
| Runtime | Node.js 24.x | Python 3.13.x |
| Context output path | context.outputDir | context.output_dir |
| Network | denied | denied |
| Package installation | not available | not available |
| Filesystem | ephemeral except Artifacts | ephemeral except Artifacts |
Node v1, Node v2, and Python v1 are independent immutable snapshots. Their exact patch versions and package inventories are captured when each snapshot is built. A workflow retains its selected version; changing the authoring default does not rewrite existing definitions.
Entry points
Node.js
BlitFlow saves Node source as an .mjs module and invokes its default export:
export default async function (inputs, context) {
return { result: inputs.value };
}The one-argument form remains valid. Node source must be executable JavaScript
ESM: TypeScript syntax, CommonJS require(), and module.exports are not
transpiled or supported.
Python
BlitFlow saves Python source as source.py and invokes main:
def main(inputs, context):
return {"result": inputs["value"]}main(inputs) and main(inputs, context) are both valid. main may be
synchronous or async. The result must be a plain dict with string keys and
strict JSON values. NaN, infinity, bytes, sets, non-string keys, cycles, and
custom objects are rejected — including NumPy and pandas scalars and arrays:
return float(x), int(x) or .tolist(). An exception raised inside main is a code
failure; BlitFlow does not reinterpret it as an argument-count error.
For both languages, inputs is keyed by declared ports, required outputs must
exist, optional outputs may be omitted, and extra outputs fail the step. stdout
and stderr are bounded diagnostics and never outputs.
Node.js imports
The Node.js 24 standard library is installed. Import built-ins through node:
specifiers so generated code cannot confuse them with third-party packages.
| Task | Available imports |
|---|---|
| Files and paths | node:fs, node:fs/promises, node:path |
| Bytes and streams | node:buffer, node:stream, node:stream/promises, node:string_decoder |
| Hashing and compression | node:crypto, node:zlib |
| URLs and utilities | node:url, node:util, node:events, node:timers/promises |
import { createHash } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";Node v1 includes one external package:
| Package | Typical use |
|---|---|
simple-statistics@7.9.3 | descriptive statistics, quantiles, and variance |
Node v2 requires Node.js >=24.12.0 <25 and includes this exact public catalog:
| Category | Package |
|---|---|
| Image | sharp@0.35.3, jimp@1.6.1, @napi-rs/canvas@1.0.7, exifr@7.1.3 |
| Audio and video | @napi-rs/webcodecs@1.4.0 |
| glTF and GLB | @gltf-transform/core@4.4.2, @gltf-transform/extensions@4.4.2, @gltf-transform/functions@4.4.2 |
| Statistics and tables | simple-statistics@7.9.3, mathjs@15.2.0, arquero@8.0.3, apache-arrow@21.2.0 |
| Analytical SQL | @duckdb/node-api@1.5.5-r.4 |
| Documents | pdf-lib@1.17.1, exceljs@4.4.0, docx@9.7.1 |
| HTML, XML, validation | cheerio@1.2.0, fast-xml-parser@5.11.0, ajv@8.20.0, zod@4.4.3 |
| Structured formats | yaml@2.9.0, csv-parse@7.0.2, csv-stringify@6.8.3 |
| Dates, text, compression | date-fns@4.4.0, fastest-levenshtein@1.0.16, fflate@0.8.3 |
| Graphs | graphology@0.26.0, graphology-library@0.8.0 |
sharp is not available in Node v1. New Node definitions use v2; explicitly
pin version 1 only when preserving its smaller legacy environment. axios and
@blitflow/sdk are not available inside either Sandbox environment. Other
packages from your application are not installed.
Network modules may exist in the standard library, but outbound connections
are denied. Do not run npm, npx, yarn, pnpm, or bun install.
Python imports
Python v1 includes the following exact public catalog. Use the import name in the second column, not necessarily the distribution name. Transitive packages are locked for the snapshot but are not a stable authoring surface.
| Installed distribution | Import name | Primary use |
|---|---|---|
beautifulsoup4@4.15.0 | bs4 | HTML parsing |
duckdb@1.5.5 | duckdb | in-process SQL analytics |
imageio@2.37.4 | imageio | image reading and writing |
jsonschema@4.26.0 | jsonschema | JSON Schema validation |
lxml@6.1.1 | lxml | XML and HTML parsing |
matplotlib@3.11.1 | matplotlib | headless plotting to files |
networkx@3.6.1 | networkx | graph algorithms |
numpy@2.5.2 | numpy | arrays and numerical computing |
opencv-python-headless@5.0.0.93 | cv2 | computer vision without a GUI |
openpyxl@3.1.5 | openpyxl | reading and writing XLSX files |
orjson@3.12.0 | orjson | fast JSON encoding and decoding |
pandas@3.0.5 | pandas | tabular dataframes |
pillow@12.3.0 | PIL | image processing |
plotly@6.9.0 | plotly | chart figures and structured chart data |
polars@1.43.2 | polars | columnar dataframes |
pyarrow@25.0.1 | pyarrow | Arrow and Parquet data |
pydantic@2.13.4 | pydantic | typed data validation |
pypdf@6.16.1 | pypdf | reading and transforming PDFs |
python-dateutil@2.9.0.post0 | dateutil | date parsing and arithmetic |
python-docx@1.2.0 | docx | reading and writing DOCX files |
pyyaml@6.0.3 | yaml | YAML parsing and serialization |
rapidfuzz@3.14.5 | rapidfuzz | fuzzy string matching |
reportlab@5.0.0 | reportlab | PDF generation |
scikit-image@0.26.0 | skimage | image processing and analysis |
scikit-learn@1.9.0 | sklearn | classical machine learning |
scipy@1.18.0 | scipy | scientific algorithms |
seaborn@0.13.2 | seaborn | statistical visualization |
statsmodels@0.14.6 | statsmodels | statistical models and tests |
sympy@1.14.0 | sympy | symbolic mathematics |
xlsxwriter@3.2.9 | xlsxwriter | generating XLSX files |
- PyTorch is not installed.
- TensorFlow is not installed.
- Transformers is not installed.
- Diffusers is not installed.
Choose a catalog/provider node for workloads that require those model runtimes.
Python runs with user site packages disabled, bytecode writes disabled, a headless Matplotlib backend, and bounded native-library thread counts. Do not run pip, uv, conda, poetry, or another installer from user code.
Filesystem and Artifacts
Every attempt receives a fresh filesystem. FILE, IMAGE, AUDIO, and VIDEO inputs are read-only local descriptors in both languages:
type CodeArtifactInput = {
path: string;
mimeType: string;
sizeBytes: number;
};Use the language-specific context path for outputs:
// Node
export default async function ({ text }, { outputDir }) {
const path = outputDir + "/report.txt";
await (await import("node:fs/promises")).writeFile(path, text);
return { report: { path, mimeType: "text/plain" } };
}# Python
from pathlib import Path
def main(inputs, context):
path = Path(context.output_dir) / "report.txt"
path.write_text(inputs["text"], encoding="utf-8")
return {"report": {"path": str(path), "mimeType": "text/plain"}}Only declared FILE, IMAGE, AUDIO, and VIDEO outputs are collected and persisted. Never hard-code internal Sandbox paths.
The returned mimeType is checked against the detected bytes. Typed media
ports accept closed allowlists; FILE takes any passive MIME:
| Port | Accepted mimeType |
|---|---|
| IMAGE | image/png, image/jpeg, image/webp, image/gif, image/avif |
| AUDIO | audio/wav, audio/mpeg, audio/aac, audio/flac, audio/ogg (MP4/M4A audio is not accepted) |
| VIDEO | video/mp4, video/webm, video/quicktime, video/matroska |
| FILE | any passive MIME, defaulting to application/octet-stream; a declared MIME must be compatible with the bytes' signature |
SVG, HTML, XML, JavaScript, and other active content are rejected on every port. See Code nodes for size limits and chaining examples.
Sandbox restrictions
These restrictions apply identically to Node and Python:
| Area | Restriction |
|---|---|
| Lifetime | Every attempt uses a fresh, non-persistent Sandbox. The Sandbox and its full process tree stop after success, failure, or timeout; background processes do not survive. |
| Network | The snapshot is switched to deny-all outbound networking before publication and execution has no exposed ports. |
| Identity | User code runs as an unprivileged user with no Linux capabilities, no supplementary groups, and no ability to gain privileges. |
| Environment | User code receives a sanitized environment allowlist. Application secrets and provider credentials are not forwarded. |
| Runtime | Installed runtimes and packages are a root-owned, read-only runtime. Runtime package installation is unavailable. |
| Filesystem | Temporary writes are ephemeral. Only declared FILE/IMAGE/AUDIO/VIDEO outputs written below the supplied output directory become durable Artifacts. |
The process supervisor also enforces these per-attempt limits:
| Limit | Current contract |
|---|---|
| Source | 64 KiB UTF-8 |
| Ports | 16 inputs and 16 outputs |
| Encoded JSON input | 10 MiB |
| Encoded JSON result | 10 MiB |
| stdout / stderr | 1 MiB each |
| Binary Artifact | 200 MiB per file; 400 MiB across inputs and outputs |
| Processes | 128 processes |
| Address space | 4 GiB per user process |
| Timeout | 1–900 seconds; default 300 |
| Compute | 1, 2, or 4 vCPUs; default 2 |
Timeouts, missing imports, syntax errors, exceptions, and invalid results fail the step. Public errors do not contain stdout, stderr, internal paths, private Artifact URLs, or provider details.