Skip to content
Back to skills

N8n Code Javascript

ASecurity

Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input/$json/$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.

  • 18 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 26, 2026
developmentjavascriptjavanodeapidatabase

Works with

  • api

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add neurawork-git/n8n-autopilot --skill n8n-code-javascript --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of N8n Code Javascript?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for N8n Code Javascript
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/neurawork-git-n8n-code-javascript/badge)](https://www.skillsdirectory.com/skills/neurawork-git-n8n-code-javascript)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: n8n-code-javascript
description: Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input/$json/$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.
user-invocable: false
---

# JavaScript Code Node

Expert guidance for writing JavaScript code in n8n Code nodes.

---

## Quick Start

```javascript
// Basic template for Code nodes
const items = $input.all();

// Process data
const processed = items.map(item => ({
  json: {
    ...item.json,
    processed: true,
    timestamp: new Date().toISOString()
  }
}));

return processed;
```

### Essential Rules

1. **Choose "Run Once for All Items" mode** (recommended for most use cases)
2. **Access data**: `$input.all()`, `$input.first()`, or `$input.item`
3. **CRITICAL**: Must return `[{json: {...}}]` format
4. **CRITICAL**: Webhook data is under `$json.body` (not `$json` directly)
5. **Built-ins available**: $helpers.httpRequest(), DateTime (Luxon), $jmespath()

---

## When NOT to use a Code node (native-first)

Reach for a native node before writing JavaScript — Code nodes are harder to read, review, and they
run V8 in-process (OOM risk on large data, see below). In a real production audit, Code nodes
outnumbered native conditional nodes ~2.5:1 — much of it avoidable:

| If you are doing… | Use this native node, NOT Code |
|---|---|
| Branching on a condition | `IF` (2 branches) / `Switch` (n branches) |
| Dropping items by a rule | `Filter` |
| Setting / renaming / mapping fields | `Set` (Edit Fields) |
| Merging / combining streams | `Merge` |
| Aggregating into one item | `Aggregate` / `Summarize` |
| Looping over large batches | `Loop Over Items (SplitInBatches)` |

> **Memory / OOM (real production incident):** a Code node that loads or iterates a large dataset —
> especially a full DB result set (>~10k rows), binary, or file contents — can spike the V8 heap
> (~3 GB cap) and **crash the n8n pod (OOM)**. For large data: page/limit at the source, process in
> `SplitInBatches`, or push the work into the database/native node instead of materializing it all in JS.

Use a Code node when the logic genuinely has no native equivalent (custom parsing, multi-field
computation, shaping a bespoke payload).

## Mode Selection Guide

### Run Once for All Items (Recommended - Default)

**Use for:** aggregation, batch processing, transformations that have no native-node equivalent

```javascript
const allItems = $input.all();
const total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);

return [{
  json: { total, count: allItems.length, average: total / allItems.length }
}];
```

### Run Once for Each Item

**Use for:** Specialized cases — per-item validation, independent operations

```javascript
const item = $input.item;

return [{
  json: { ...item.json, processed: true, processedAt: new Date().toISOString() }
}];
```

**Decision:** Need to compare multiple items? → All Items. Each item independent? → Each Item. Not sure? → All Items.

---

## Data Access Patterns

```javascript
// Most common: all items
const allItems = $input.all();

// Single result
const firstItem = $input.first();
const data = firstItem.json;

// Reference other nodes
const webhookData = $node["Webhook"].json;
const httpData = $node["HTTP Request"].json;
```

---

## CRITICAL: Webhook Data Structure

Webhook data is nested under `.body`:

```javascript
// ❌ WRONG
const name = $json.name;

// ✅ CORRECT
const name = $json.body.name;
const webhookData = $input.first().json.body;
```

---

## Return Format Requirements

```javascript
// ✅ Single result
return [{ json: { field1: value1 } }];

// ✅ Multiple results
return items.map(item => ({ json: { id: item.json.id, processed: true } }));

// ✅ Empty result
return [];
```

**WRONG:** `return {json: {...}}` (no array), `return [{field: value}]` (no json key)

---

## Built-in Functions

### $helpers.httpRequest()

```javascript
const response = await $helpers.httpRequest({
  method: 'GET',
  url: 'https://api.example.com/data',
  headers: { 'Authorization': 'Bearer token' }
});

return [{ json: { data: response } }];
```

### DateTime (Luxon)

```javascript
const now = DateTime.now();
const formatted = now.toFormat('yyyy-MM-dd');
const tomorrow = now.plus({ days: 1 });
```

### $jmespath()

```javascript
const adults = $jmespath(data, 'users[?age >= `18`]');
const names = $jmespath(data, 'users[*].name');
```

---

## Common Patterns

### Aggregation

```javascript
const items = $input.all();
const total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);

return [{ json: { total, count: items.length, average: total / items.length } }];
```

### Filtering + Transformation

```javascript
return $input.all()
  .filter(item => item.json.status === 'active')
  .map(item => ({ json: { id: item.json.id, name: item.json.name } }));
```

### Error Handling

```javascript
try {
  const response = await $helpers.httpRequest({ url: 'https://api.example.com/data' });
  return [{ json: { success: true, data: response } }];
} catch (error) {
  return [{ json: { success: false, error: error.message } }];
}
```

---

### Hardened instances deny `$env` and `require()` (#97)

Production instances commonly run with `N8N_BLOCK_ENV_ACCESS_IN_NODE=true` and an empty
`NODE_FUNCTION_ALLOW_BUILTIN` / `NODE_FUNCTION_ALLOW_EXTERNAL`. There, `$env.SECRET` throws
*access to env vars denied* and `require('crypto')` throws *Module crypto is disallowed* — at
runtime, after every gate was green. Do not build on either:

- Secrets → a credential on a native node (HTTP Request with `httpHeaderAuth`, …), never `$env`.
- HMAC / hashing → the **Crypto** node (`n8n-nodes-base.crypto`), not `require('crypto')`.
- If Code must use a builtin, the sticky note names the instance setting it depends on, and the
  push-lint gate warns (`code-env-access`) so the reviewer checks the target instance allows it.

---

## Top 5 Mistakes

1. **No return statement** → Add `return items.map(item => ({json: item.json}));`
2. **Using `{{ }}` in Code node** → Use `$json.field` directly (no braces)
3. **Wrong return wrapper** → Must be `[{json: {...}}]`, not `{json: {...}}`
4. **Missing null checks** → Use `item.json?.user?.email || 'fallback'`
5. **Webhook body** → `$json.email` ❌ → `$json.body.email` ✅

---

## Best Practices

- Always validate input: `if (!items || items.length === 0) return [];`
- Use try-catch for async operations
- Prefer `map`/`filter` over manual loops
- Filter early, process late
- Debug with `console.log()`

---

## When to Use Code Node

✅ Complex transformations, custom calculations, API response parsing, multi-step conditionals, data aggregation

❌ Simple field mapping → Set node | Basic filtering → Filter node | HTTP requests → HTTP Request node

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.