n8n-code-javascript について
n8n Code ノードで JavaScript を書くためのガイドスキルです。ワークフロー構築者向けに、実行モードやデータアクセス、戻り値、サンドボックスの注意点を説明します。
主な機能
- 01一括または項目ごとの実行モード選択
- 02入力と Webhook データの読み取り
- 03有効な n8n アイテムの返却
- 04JavaScript によるデータ変換パターン
- 05サンドボックスのヘルパーとモジュールの説明
活用シーン
- 01ワークフロー項目の集計やフィルタリング
- 02Code ノードでのデータ変換
- 03戻り値形式エラーの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ czlonkowski/ n8n-mcp --skill n8n-code-javascriptインストール後、Claude Code で/n8n-code-javascriptを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
BUILTIN_FUNCTIONS.mdCOMMON_PATTERNS.mdDATA_ACCESS.mdERROR_PATTERNS.mdREADME.md詳細
JavaScript コードノード
n8n の Code ノードで 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;
基本ルール
- 「Run Once for All Items」モードを選択します(ほとんどのユースケースで推奨)
- データにアクセスします:
$input.all()、$input.first()、または$input.item [{json: {...}}]を返します — これはモード間で移植可能な標準形式です。Run Once for All Items モードでは、return {…}のようなオブジェクトだけを返しても n8n が自動的にラップするため、こちらも動作します。本当にエラーになるのは、プリミティブ値(文字列/数値)またはnullを返した場合です。- 重要:Webhook データは
$json直下ではなく、$json.bodyの下にあります。 - 利用可能な組み込み機能:
this.helpers.httpRequest()(認証なし — タスクランナーのサンドボックスでは、単独の$helpersグローバルは 未定義 であるため、$helpers.httpRequest()はReferenceError: $helpers is not definedをスローします)、DateTime(Luxon)、$jmespath()。利用できない機能:this.helpers.httpRequestWithAuthentication(許可リストで禁止されています)、$env(N8N_BLOCK_ENV_ACCESS_IN_NODE=true の場合)、require()(許可リストにある場合を除く)。単純な認証なし GET 以外(認証、ページネーション、再試行)には、HTTP Request ノードを優先し、Code ノードは純粋なロジックに使用します。 - インスタンスで許可リストに登録されたライブラリ:セルフホストのインスタンスでは、
N8N_RUNNERS_ALLOWED_BUILT_IN_MODULESおよびN8N_RUNNERS_ALLOWED_EXTERNAL_MODULES(旧設定:NODE_FUNCTION_ALLOW_BUILTIN/NODE_FUNCTION_ALLOW_EXTERNAL)を使ってモジュールを許可リストに登録できます。ユーザーがインスタンスで特定のモジュール(例:axios、lodash、crypto)を許可していると伝えた場合は、require()で使用し、拒否しないでください。不明な場合は確認するか、組み込み機能のみを使用することを既定とします。 - 別のスキルが必要ですか? AI Agent にアタッチされた Custom Code Tool(
@n8n/n8n-nodes-langchain.toolCode)向けのコードを書く場合は、そこで作業を中止してください。このノードは契約が異なります(入力はquery経由、文字列を返す必要があり、$input/$helpersはありません)。n8n-code-tool スキルを使用してください。
モード選択ガイド
Code ノードには 2 つの実行モードがあります。ユースケースに合わせて選択してください。
Run Once for All Items(推奨 - デフォルト)
このモードの使用対象: ユースケースの 95%
- 仕組み:入力数にかかわらず、コードを 1 回 実行します
- データアクセス:
$input.all()またはitems配列 - 最適な用途:集計、フィルタリング、バッチ処理、変換、すべてのデータを使った API 呼び出し
- パフォーマンス:複数のアイテムを処理する場合に高速です(実行は 1 回)
// Example: Calculate total from all items
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
このモードの使用対象: 特定のケースのみ
- 仕組み:入力アイテムごとにコードを 個別に 実行します
- データアクセス:
$input.itemまたは$item - 最適な用途:アイテム固有のロジック、独立した処理、アイテムごとの検証
- パフォーマンス:大規模なデータセットでは低速です(複数回実行)
// Example: Add processing timestamp to each item
const item = $input.item;
return [{
json: {
...item.json,
processed: true,
processedAt: new Date().toISOString()
}
}];
使用する場合:
- ✅ 各アイテムで個別の API 呼び出しが必要な場合
- ✅ エラー処理が異なる、アイテムごとの検証が必要な場合
- ✅ アイテムのプロパティに応じた、アイテム固有の変換を行う場合
- ✅ ビジネスロジック上、アイテムを個別に処理する必要がある場合
選択の目安:
- 複数のアイテムを参照する必要がありますか? → 「All Items」モードを使用します
- 各アイテムは完全に独立していますか? → 「Each Item」モードを使用します
- 判断できませんか? → 「All Items」モードを使用します(必要に応じて内部でループできます)
「All Items」がより高速な理由 — アイテムごとの境界
Code ノードでは、モードの選択がパフォーマンスに最も大きく影響します。アイテムごとの実行コンテキストには、それぞれセットアップコストがかかります(n8n 2.x、小さなレコードで測定)。
| アイテムごとに実行されるもの | おおよそのコスト |
|---|---|
| Code All Items(全体を一度に実行) | 約0.02 ms/アイテム |
| 任意のノードの式(IF / Set など) | 約0.2 ms/アイテム |
| Code Each Item(アイテムごとに完全なサンドボックス) | 約0.6 ms/アイテム — All Items の約25〜30倍 |
10k件のアイテムに対して Run Once for Each Item を使用すると、純粋なオーバーヘッドだけで約6秒かかりますが、Run Once for All Items なら約0.2秒です。各アイテムを個別に処理する必要が本当にある場合(個別のエラー処理や、バッチ化できないアイテムごとのAPI呼び出しなど)に限り、Each Item を使用してください。それ以外の場合は、1つの All Items ノード内でループします。式の複雑さによるコストは実質的に無視できるほど小さく(コストの約90%はコードではなく、アイテムごとのコンテキストによるものです)、ノード間のホップごとにすべてのアイテムが再コピーされます。そのため、それぞれを細かく最適化するのではなく、アイテムごとの境界の数を減らしてください。数百件未満なら、これらは問題になりません。大量のアイテムを処理し、I/Oが少ないホットパスで活用してください。
参照:DATA_ACCESS.md → 「Mode Performance」で、関連事項、ホップのコスト、スケールの確認方法を説明しています。
データアクセスのパターン
上流ノードからデータを取得する4つの方法です。$node["Name"] と $('Name') では .first().json または .all() が必要です。.json を直接使うことはできません。
const allItems = $input.all(); // 1. All items — batch ops, aggregation (most common)
const data = $input.first().json; // 2. First item — single objects, API responses
const item = $input.item; // 3. Current item — "Each Item" mode ONLY (undefined otherwise)
const other = $node["Webhook"].json; // 4. Named node — combine data across nodes
フィールドには必ず .json 経由でアクセスしてください(例:item.json.name。item.name ではありません)。また、単独の $json.field より、明示的な $input.first().json.field を優先してください。
参照:DATA_ACCESS.md に完全なガイドがあります。各パターンの例、判断ツリー、よくあるミス(元データの変更、長さチェックの欠落、誤ったモードでの $input.item の使用)を説明しています。
重要:Webhook のデータ構造
最もよくあるミス:Webhook データは .body の下にネストされています。
// ❌ WRONG - Will return undefined
const name = $json.name;
const email = $json.email;
// ✅ CORRECT - Webhook data is under .body
const name = $json.body.name;
const email = $json.body.email;
// Or with $input
const webhookData = $input.first().json.body;
const name = webhookData.name;
理由:Webhook ノードはすべてのリクエストデータを body プロパティの下に格納します。これには POST データ、クエリパラメーター、JSON ペイロードが含まれます。
参照:DATA_ACCESS.md で Webhook のデータ構造の詳細を確認してください。
戻り値の形式に関する要件
標準形式:[{json: {...}}] — 各オブジェクトが json プロパティを持つオブジェクトの配列です。曖昧さがなく、どちらの実行モードでも同じように動作するため、デフォルトとして使用してください。
Run Once for All Items モードでは、n8n は出力時に緩い形式を自動で正規化します。単一の json を持たないオブジェクトや、json を持たないオブジェクトの配列は、自動的に json の下にラップされます。そのため、return {foo: 1} は実行できます。一方、ラップする対象がなく、実行時に「Code doesn't return items properly」エラーになるのは、プリミティブ値(文字列/数値/ブール値)または null/undefined です。(n8n-mcp ≥ 2.63.0 では、オブジェクトをそのまま返してもエラーとして扱われなくなりました。これは、この自動ラップ動作を反映しています。)
正しい戻り値の形式
// ✅ Single result
return [{
json: {
field1: value1,
field2: value2
}
}];
// ✅ Multiple results
return [
{json: {id: 1, data: 'first'}},
{json: {id: 2, data: 'second'}}
];
// ✅ Transformed array
const transformed = $input.all()
.filter(item => item.json.valid)
.map(item => ({
json: {
id: item.json.id,
processed: true
}
}));
return transformed;
// ✅ Empty result (when no data to return)
return [];
// ✅ Conditional return
if (shouldProcess) {
return [{json: processedData}];
} else {
return [];
}
標準形式ではない戻り値(自動でラップされます — 標準形式を推奨)
// ⚠️ Auto-wrapped in All Items mode → [{json: {field: value}}]. Runs, but prefer the array form.
return {
json: {field: value}
};
// ⚠️ Auto-wrapped → [{json: {field: value}}]. Runs, but add the json wrapper for clarity.
return [{field: value}];
// ✅ Fine — input items already carry a json property, so returning them unchanged is a valid passthrough
return $input.all();
実際に無効な戻り値
// ❌ FAILS: primitive — n8n errors "Code doesn't return items properly"
return "processed";
// ❌ FAILS: null / undefined — nothing to pass to the next node
return null;
重要な理由:標準形式の [{json: {...}}] は曖昧さがなく、どちらのモードでも同じように動作します。n8n は All Items モードで、オブジェクト単体やオブジェクトの配列を自動的に正規化します。しかし、プリミティブ値や null の戻り値にはラップする対象がないため、実行が停止します。
参照:ERROR_PATTERNS.md #3 で、エラーの詳しい解決方法を確認してください。
よく使うパターンの概要
本番ワークフローでよく使われる Code ノードの形を紹介します。まずは簡単な例として、すべてのアイテムを合計・集計します。
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 } }];
完全なライブラリには10種類のパターンが含まれています。複数ソースの集計、正規表現によるフィルタリング、Markdown/構造化テキストの解析、JSON の比較、CRM/フォームの変換、リリース処理、計算フィールドを使った配列変換、Slack Block Kit の書式設定、上位N件のランキング、文字列集計レポートなどがあり、それぞれにバリエーションがあります。
参照:COMMON_PATTERNS.md に、本番で使える10種類の詳しいパターンがあります(また、ベストプラクティスのセクションでは、入力値の検証、try-catch、早期のフィルタリング、ループより配列メソッドを使う方法、console.log によるデバッグを紹介しています)。
エラーの防止 - よくある間違い
Code ノードで繰り返し発生する失敗を、おおよその頻度順に示します。
- コードが空/return がない — 必ず最後に
return [...]を記述し、すべての分岐で値を返すようにしてください。 - 式の構文をコードとして使用 — JavaScript を記述する場所に
{{ }}を書かないでください(return {{ $json.x }}は構文エラーです)。`${$json.field}`または$input.first().json.fieldを使用してください。文字列リテラル内の{{ }}は問題ありません。n8n が評価しない、単なる文字列です。 - 戻り値の形式 —
return [{json:{...}}]を推奨します。単独のreturn {…}は All Items モードで自動的にラップされますが、実際にエラーになるのはプリミティブ値(文字列/数値)やnullを返した場合です。 - null チェックがない — オプショナルチェーンを使用してください:
item.json?.user?.email || 'fallback'。 - Webhook の本文のネスト —
$json.emailは未定義です。$json.body.emailを使用してください。 - 認証ヘルパーがブロックされる(
httpRequestWithAuthentication)および$envがブロックされる — シークレットは Code ノードのサンドボックスではなく、クレデンシャル/HTTP Request ノード経由で扱ってください。
参照:ERROR_PATTERNS.md には包括的なガイドがあります。各エラーの誤ったコードと正しいコード、エスケープのルール、サンドボックスの制限(エラー #6~#7)、防止チェックリスト、エラーメッセージのクイック検索表を掲載しています。
組み込み関数とヘルパー
// HTTP requests (no auth — see sandbox note below)
const res = await this.helpers.httpRequest({ method: 'GET', url: 'https://api.example.com/data' });
// DateTime (Luxon): now, formatting, arithmetic
const now = DateTime.now();
const formatted = now.toFormat('yyyy-MM-dd');
const tomorrow = now.plus({ days: 1 });
// $jmespath() — query JSON structures
const adults = $jmespath($input.first().json, 'users[?age >= `18`]');
// $getWorkflowStaticData() — data that persists across executions
サンドボックス(n8n v2.0 の JsTaskRunnerSandbox 以降):アクセサーは this.helpers.httpRequest() です。この環境では $helpers グローバルは未定義です($helpers.httpRequest() は ReferenceError をスローします)。this が失われるネストされた非同期関数内では、await fn.call(this, ...) のように呼び出してください。this.helpers.httpRequestWithAuthentication と this.helpers.requestWithAuthenticationPaginated は拒否リストに登録されています(→ UnsupportedFunctionError)。認証付きの呼び出しには、クレデンシャルを設定した HTTP Request ノード(推奨)、サブワークフロー、またはトークンがすでにワークフロー内をデータとして流れている場合に限り this.helpers.httpRequest() に手動で Authorization: Bearer ${token} ヘッダーを指定する方法を使用してください。N8N_BLOCK_ENV_ACCESS_IN_NODE=true の場合、$env はブロックされます。require() が機能するのは、許可リストに登録されたモジュールのみです。Buffer、URL、および標準の JavaScript グローバル(Math、JSON、Object、Array)は常に使用できます。
参照:BUILTIN_FUNCTIONS.md には完全なリファレンスがあります。httpRequest の全オプション、DateTime/Luxon のすべての操作、JMESPath のパターン、静的データの使用例、サンドボックス制限の詳細を掲載しています。
ベストプラクティス
- 最初に入力を検証する — 処理の前に、配列が空でないか、
.jsonが存在するかを確認してください。 - リスクのある処理(HTTP 呼び出しなど)は try-catch で囲む。クラッシュさせず、エラーオブジェクトを返してください。
- 手動のループより配列メソッド(
filter/map/reduce)を優先してください。 - 早めにフィルタリングし、変換は後で行う — コストのかかる処理の前にデータセットを絞り込んでください。
- わかりやすい名前を付け、デバッグには
console.log()を使用してください(出力はブラウザーのコンソールに表示されます)。
参照:COMMON_PATTERNS.md →「ベストプラクティス」には、それぞれのコード例があります。
本番環境での注意点
実際のデプロイで得られた貴重な教訓を、DATA_ACCESS.md →「本番環境での注意点」にまとめています。
- SplitInBatches の出力は直感に反します:
main[0]= 完了(すべてのバッチの処理後に1回だけ実行)、main[1]= 各バッチ(ループ本体)です。安全策として、完了出力の後に Limit 1 ノードを追加してください。 - コストを左右するのは反復回数です:ループの各反復では、エンジンを通じて本体全体が再実行されます(1回あたり約0.8 msのオーバーヘッド)。
batchSize: 1は Each Item と同等のループです。実際の制約(レート制限、ページサイズ、メモリ)が許す最大のバッチサイズを使用するか、ループ自体を使わないでください。 - 反復をまたぐ蓄積(重大):ループ後に
$('Node Inside Loop').all()を呼び出しても、直近の反復のアイテムだけが返されます。$getWorkflowStaticData('global')を使って蓄積してください(処理前にリセットし、ループ内で追加し、処理後に読み取ります)。 - pairedItem:入力と1対1に対応しないアイテムを出力する場合は、
pairedItem: { item: i }を設定してください。設定しないと、後続の Set ノードでpaired_item_no_infoエラーが発生します。 - ノード参照の構文:
$('Node').first().jsonまたは$('Node').all()を使います。参照に対して.jsonを直接使ってはいけません。 - 浮動小数点の精度:浮動小数点の誤差による誤検出を避けるため、通貨はセント単位で比較します。
Math.round(a*100) !== Math.round(b*100)を使ってください。
Code ノードを使う場合
Code ノードを使う前に、n8n Expression Syntax スキルの変換ゲートキーパーに従ってください。式 → Edit Fields フィールド内のアロー関数 IIFE → Code ノードの順に検討します。最初の2つの方法で、ほとんどの「このデータを変換する」タスクをそれぞれ約1~10 msで処理できます。一方、サンドボックス内で実行される Code ノードは約500~1000 msかかります。単一アイテムの整形だけなら約100倍の差がありますが、機能上の違いはありません。Code ノードを使う価値があるのは、データセット全体の集計(
$input.all())、許可リストにあるライブラリの利用、または非同期処理の場合に限られます。また、暗号処理(HMAC、ハッシュ化、署名)や XML/SOAP/RSS の解析をコードで実装する前に、ネイティブノードがないか確認してください。n8n には、JavaScriptを使わずにこれらを処理できる Crypto ノード(nodes-base.crypto)と XML ノード(nodes-base.xml)があります。ネイティブノードでできる処理に Code ノードを使うのは、よくある誤った選択の1つです。
次の場合は Code ノードを使います。
- ✅ 複数のステップが必要な複雑な変換
- ✅ カスタム計算やビジネスロジック
- ✅ 再帰処理
- ✅ 複雑な構造を持つ API レスポンスの解析
- ✅ 複数ステップの条件分岐
- ✅ アイテムをまたぐデータ集計
次の場合は他のノードを検討します。
- ❌ 単純なフィールドのマッピング → Set ノードを使用
- ❌ 基本的なフィルタリング → Filter ノードを使用
- ❌ 単純な条件分岐 → IF または Switch ノードを使用
- ❌ HTTP リクエストのみ → HTTP Request ノードを使用
Code ノードが得意なこと:単純なノードを多数つなぐ必要がある複雑なロジック
他のスキルとの連携
連携するスキル:
n8n Expression Syntax:
- 他のノードでは
{{ }}構文を使って式を記述します - Code ノードでは JavaScript を直接使います(
{{ }}は使いません) - 式とコードの使い分け
n8n MCP Tools Expert:
- Code ノードの検索方法:
search_nodes({query: "code"}) - 設定方法の確認:
get_node({nodeType: "nodes-base.code"}) - コードの検証:
validate_node({nodeType: "nodes-base.code", config: {...}})
n8n Node Configuration:
- モードの選択(All Items と Each Item)
- 言語の選択(JavaScript と Python)
- プロパティの依存関係の理解
n8n Workflow Patterns:
- 変換ステップでの Code ノードの使用
- Webhook → Code → API のパターン
- ワークフローでのエラー処理
n8n Validation Expert:
- Code ノードの設定の検証
- 検証エラーへの対処
- よくある問題の自動修正
クイックリファレンスチェックリスト
Code ノードをデプロイする前に、以下を確認してください。
- コードが空でない - 意味のあるロジックが必要です
- return 文がある - プリミティブ値や
nullではなく、アイテムを返します - 標準的な戻り値の形式 - 各アイテムは
{json: {...}}です(オブジェクトのみでも自動的にラップされますが、明示してください) - データアクセスが正しい -
$input.all()、$input.first()、または$input.itemを使用しています -
{{ }}をコードとして記述していない - JavaScript のテンプレートリテラルを使用します:`${value}` - エラー処理 - null/undefined の入力に対するガード節があります
- Webhook データ - Webhook からのデータの場合は
.body経由でアクセスします - モードの選択 - ほとんどの場合、「All Items」を選択します
- パフォーマンス - 手動ループよりも map/filter を優先します
- 一貫した出力 - すべてのコードパスで同じ構造を返します
追加リソース
関連ファイル
- DATA_ACCESS.md - データアクセスパターンの詳細
- COMMON_PATTERNS.md - 本番環境で検証済みの10種類のパターン
- ERROR_PATTERNS.md - よくあるエラー上位5件と解決方法
- BUILTIN_FUNCTIONS.md - 組み込み機能の完全なリファレンス
n8n のドキュメント
- Code ノードガイド: https://docs.n8n.io/code/code-node/
- 組み込みメソッド: https://docs.n8n.io/code-examples/methods-variables-reference/
- Luxon のドキュメント: https://moment.github.io/luxon/
n8n の Code ノードで JavaScript を書く準備ができました! まずは簡単な変換から始め、よくあるミスを避けるためにエラーパターンガイドを活用し、本番環境ですぐに使える例についてはパターンライブラリを参照してください。