@warnyin/n8n-nodes-code-plus
v0.1.29
Published
n8n node that runs user code with installable cached libraries
Readme
Code Plus — n8n Community Node
Run custom JavaScript with installable npm libraries and a persistent cache.
Package: @warnyin/n8n-nodes-code-plus
⚠️ BREAKING CHANGE in v0.1.24: API now matches n8n standard. Use
$input.all()and$input.itemwith.jsonproperty accessor. See CHANGELOG.md for migration guide.
Table of Contents
- About
- Key Features
- Installation
- Usage
- Quick Start
- n8n Code (compat) Examples
- Detailed Parameters & Behavior
- Examples
- Notes & Limitations
- Roadmap
- Development
- Changelog
- License
- References
About
- Install npm libraries directly from the node UI (comma-separated or JSON array).
- Cache libraries in a persistent directory for reuse and faster runs.
- Optional Init Code that runs once before the main code.
- Mode: Run Once for Each Item, Run Once for All Items, or n8n Code (compat).
- Control Timeout, clear cache, and force reinstall.
- Executes in a restricted VM with a custom
requirebound to the cache.
Documentation structure is inspired by the author’s Swagger API node for n8n reference.
Key Features
- On-the-fly npm dependency installation.
- Supports both comma-separated and JSON array input for libraries.
- Persistent cache directory (default
~/.n8n/code-plus-cache). - Select
Mode:Run Once for Each Item,Run Once for All Items, orn8n Code (compat). - Language selector: JavaScript (Python options are visible but not supported in this node).
- Safety options: Timeout, Clear Cache, Force Reinstall, Preinstall Only.
require()is scoped to the cache directory for controlled loading.
Installation
Option 1: Community Nodes (Recommended)
- Open n8n and go to
Settings → Community Nodes - Click
Install - Enter:
@warnyin/n8n-nodes-code-plus - Accept the risks and install
Option 2: Manual Installation
cd ~/.n8n/nodes
npm install @warnyin/n8n-nodes-code-plus
# Restart n8nOption 3: Local Development & Linking
# Clone, install, and build
git clone https://github.com/warnyin/n8n-nodes-code-plus.git
cd n8n-nodes-code-plus
npm install
npm run build
# Link to n8n
npm link
cd ~/.n8n
npm link @warnyin/n8n-nodes-code-plus
# Restart n8nUsage
Main Parameters
Libraries: e.g.nanoid@latest,lodashor["nanoid","dayjs@^1"]Init Code: runs once before main code- ⚠️ Important: Variables must be declared without
const/let/varto be accessible in Main Code - ✅ Correct:
nanoid = require('nanoid').nanoid; - ❌ Incorrect:
const nanoid = require('nanoid').nanoid; - Reason: Variables with const/let/var are scoped locally and not accessible outside Init Code
- ⚠️ Important: Variables must be declared without
Main Code: JavaScript whererequire()loads from the cache- Tip: Use the field's menu (
⋯) →Reset Valueto reapply example code for the currentLanguageandMode. Mode:Run Once for Each Item,Run Once for All Items, orn8n Code (compat)Language:JavaScript(Python options are visible but not supported in Code Plus)Options: Cache Directory, Clear Cache, Force Reinstall, Timeout (ms), Cache TTL (minutes), Preinstall Only
Quick Start
Example with Init Code and Main Code:
// Init Code - Load library (declare WITHOUT const/let/var)
nanoid = require('nanoid').nanoid;
// Main Code - Use the variable (Mode: Run Once for All Items)
for (const item of $input.all()) {
item.json.id = nanoid();
}
return $input.all();Simple Main Code without Init Code:
// Mode: Run Once for Each Item
const { nanoid } = require('nanoid');
$input.item.json.id = nanoid();
return $input.item;n8n Code (compat) Examples
- Modify items in-place like the native Code node:
// Mode: n8n Code (compat)
for (const item of $input.all()) {
item.json.idx = $input.all().indexOf(item);
}
return $input.all();- Return a single item object with
json:
// Mode: n8n Code (compat)
return { json: { ok: true } };Detailed Parameters & Behavior (English)
Language
- Options:
JavaScript(supported),Python (Beta),Python (Native) (Beta). - Current behavior: Only
JavaScriptexecutes in Code Plus. Selecting Python shows a friendly message and prevents execution. - Roadmap: Python support via system
python+venvand/or Pyodide.
Mode
Important: Starting from v0.1.24, Code Plus uses the n8n standard API with $input.all() and $input.item.
Run Once for Each Item- Context:
$input.item(full item with.jsonproperty),$input.all()(all items),item,items,index - Execution: Runs once per input item. Outputs are paired with inputs via
pairedItem. - Returns: Array → multiple outputs for that item; Object → one output;
undefined→ passthrough current item - Best for: map/transform per item
- Example:
$input.item.json.newField = 1; return $input.item;
- Context:
Run Once for All Items- Context:
$input.all()(array of all items with.jsonproperty),items,item(first item) - Execution: Runs once for the whole batch
- Returns: Array → multiple outputs overall; Object → one output;
undefined→ passthrough all items - Best for: aggregate/summary
- Example:
for (const item of $input.all()) { item.json.newField = 1; } return $input.all();
- Context:
n8n Code (compat)- Context: full
itemanditemsobjects (not onlyjson), plusindex,$input.item,$input.all() - Execution: Iterates per item internally, like n8n's native Code node
- Returns: Native Code node style (
return items,return { json: ... },return [ ... ],returnpassthrough) - Best for: migration from the native Code node or when full item structure is required
- Context: full
Mode
Run Once for Each Item- Context:
item.json,items.map(x => x.json),index,$input.item = item.json. - Execution: Runs once per input item. Outputs are paired with inputs via
pairedItem. - Returns: Array → multiple outputs for that item; Object → one output;
undefined→ passthrough currentitem.json. - Best for: map/transform per item.
- Context:
Run Once for All Items- Context:
itemsis an array of alljsonpayloads;$input.item = items[0]?.json. - Execution: Runs once for the whole batch.
- Returns: Array → multiple outputs overall; Object → one output;
undefined→ passthrough first item’sjson(if present). - Best for: aggregate/summary.
- Context:
n8n Code (compat)- Context: full
itemanditemsobjects (not onlyjson), plusindex,$input.item = item. - Execution: Iterates per item internally, like n8n’s native Code node.
- Returns: Native Code node style (
return items,return { json: ... },return [ ... ],returnpassthrough). - Best for: migration from the native Code node or when full item structure is required.
- Context: full
Libraries
- Input formats: comma-separated (
nanoid@latest,lodash) or JSON array (["nanoid","dayjs@^1"]). - Installed into the node’s cache directory (default:
~/.n8n/code-plus-cache). Force Reinstallreinstalls even if present;Clear Cache Before Runremoves cachenode_modulesbefore installing.
Init Code
- Runs once before main code in the same VM context.
- ⚠️ Important Variable Scoping:
- Variables declared with
const/let/varare NOT accessible in Main Code - To share variables, declare without
const/let/var(global assignment) - Example:
// Init Code nanoid = require('nanoid').nanoid; // ✅ Accessible in Main Code lodash = require('lodash'); // ✅ Accessible in Main Code // DON'T DO THIS: const helper = require('some-lib'); // ❌ NOT accessible in Main Code
- Variables declared with
- Use for: preloading libraries, setting global configurations, initializing shared state
- Supports top-level
await(wrapped in async context)
Main Code
- JavaScript in a restricted VM with custom
require()bound to the cache. - Supports top-level
await/return;Timeout (ms)applies to both init and main code.
Options
Cache Directory: Path for library cache (default~/.n8n/code-plus-cache).Clear Cache Before Run: Remove cached modules before reinstalling.Force Reinstall: Reinstall libraries regardless of presence.Timeout (ms): Max execution time for init/main code.Cache TTL (minutes): Automatically clears installed libraries when the last install time exceeds this TTL.Preinstall Only: Install libraries and return a summary without running code.
Execution Context
console: Forwarded to the UI in manual mode; to stdout in execute mode whenCODE_ENABLE_STDOUT="true".$inputhelper (matches n8n standard):$input.all()returns array of all items (each item has.jsonproperty with data)$input.itemreturns current item (has.jsonproperty with data)- Access data via
$input.item.json.fieldNameoritem.json.fieldNamein loops
require(): Scoped to the cache directory for controlled loading of npm packages.- Built-ins:
Buffer,setTimeout,setInterval,clearTimeout,clearInterval. helpers: Exposes n8n helpers viahelpersin the sandbox.
Examples
Using Init Code with Libraries (Mode: Run Once for All Items)
// Libraries: nanoid@latest,lodash
// Mode: Run Once for All Items
// Init Code - Load libraries globally (NO const/let/var)
nanoid = require('nanoid').nanoid;
lodash = require('lodash');
// Main Code - Modify items and return them
for (const item of $input.all()) {
item.json.short_id = nanoid(8);
item.json.tags = lodash.uniq(item.json.tags || []);
}
return $input.all();Per-Item Processing (Mode: Run Once for Each Item)
// Libraries: nanoid@latest
// Mode: Run Once for Each Item
// Init Code
nanoid = require('nanoid').nanoid;
// Main Code - Process single item
$input.item.json.short_id = nanoid(8);
return $input.item;Generate IDs without Init Code (Mode: Run Once for All Items)
const { nanoid } = require('nanoid');
for (const item of $input.all()) {
item.json.id = nanoid();
}
return $input.all();Use lodash to chunk data (Mode: Run Once for All Items)
const _ = require('lodash');
const allItems = $input.all();
const chunks = _.chunk(allItems.map(x => x.json), 50);
return chunks.map(chunk => ({ json: { chunksCount: chunks.length, items: chunk } }));Run once and stamp a timestamp via dayjs (Mode: Run Once for All Items)
const dayjs = require('dayjs');
for (const item of $input.all()) {
item.json.processedAt = dayjs().toISOString();
}
return $input.all();Notes & Limitations
- Requires network access and permission to run
npm installon the n8n server. - Libraries are installed into the cache directory only, not into n8n itself.
require()is restricted to the cache; Node built-ins are accessible via the sandbox.- Avoid long-running or blocking code; configure
Timeout (ms)appropriately. - Python execution (
python/pythonNative) is not supported in Code Plus; use the native Code node in n8n for Python.
Troubleshooting
My field modifications don't appear in output
Problem: Code like item.newField = value doesn't show in output
Solution: Use $input.all() or $input.item with the .json property:
Mode: Run Once for All Items
// ✅ Correct - access item.json for (const item of $input.all()) { item.json.short_id = nanoid(); } return $input.all();Mode: Run Once for Each Item
// ✅ Correct - access $input.item.json $input.item.json.short_id = nanoid(); return $input.item;Mode: n8n Code (compat)
// ✅ Correct - items[i].json is the JSON object for (const item of $input.all()) { item.json.short_id = nanoid(); } return $input.all();
Variables from Init Code are not defined
Problem: ReferenceError: nanoid is not defined
Solution: Don't use const/let/var in Init Code
// ❌ Wrong
const nanoid = require('nanoid').nanoid;
// ✅ Correct
nanoid = require('nanoid').nanoid;Library not installing or not found
Problem: Cannot find module 'xxx'
Solution:
- Check Libraries field has correct package name
- Try enabling
Force Reinstalloption - Check
Clear Cache Before Runto reset cache - Verify network access and npm registry availability
Made with ❤️ for the n8n community
Roadmap
Near-term (0.1.x)
- Add UI toggle for stdout (replace
CODE_ENABLE_STDOUTenv var). - Expand
$inputand console forwarding docs with examples/screenshots. - Review default
Modeto align with the native Code node. - Concurrency control for
Run Once for Each Item. - Internationalized error messages (English/Thai) with structured details.
- Add UI toggle for stdout (replace
Python Support
- Execute Python via
venv + pipwith per-node cache. - Cross-platform handling (Windows/Linux/macOS) and compiled wheels.
- Safety: timeouts, memory limits, sanitized imports.
Python (Native)via Pyodide as a fallback when system Python is unavailable.- Language-aware editor (syntax highlight/linting for Python).
- Execute Python via
Execution & Security
- Require allowlist/denylist.
- Offline mode and dependency whitelist scanning; integrity checks via lockfile.
- Resource limits (CPU/Memory) and configurable concurrency.
- Harden sandbox and restrict accessible globals.
Features & Compatibility
- Multiple outputs and binary data support.
- Expand
$input(e.g.,first,pairedItem) to parity with the native Code node. - UI list of installed libraries with upgrade/remove actions.
- Proxy and custom registry support for installations.
UX & Developer Experience
- Template/snippet library in the editor.
- Autocomplete for
require()from installed libraries. - Debug mode with step logging and timing.
- CLI for preinstall/prune cache operations.
- Unit/integration tests and full example workflows.
Development
npm install
npm run build
# Use npm link as shown above to connect with n8nChangelog
- See
CHANGELOG.mdfor release notes.
License
- MIT License — see
LICENSE.md.
References
- [0] @warnyin/n8n-nodes-swagger-api — README structure and sections ref-swagger
