n8n-code-nodes-official について
n8n のカスタム処理で Code ノードを使うか判断するエージェント向けのスキルです。単純な変換には式や Edit Fields を優先し、複数ソースの集約など Code が適する場面も示します。
主な機能
- 01式と Code の選択手順
- 02Edit Fields のアロー関数でデータ整形
- 03複数ソースの集約に Code を使用
- 04JavaScript Code ノードの実行モード
- 05ネイティブの Crypto・XML ノードを優先
活用シーン
- 01少数フィールドの変換に Code ノードを使わない
- 02複数の上流データソースを集約
- 03XML 解析後にフィールドを抽出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ n8n-io/ skills --skill n8n-code-nodes-officialインストール後、Claude Code で/n8n-code-nodes-officialを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.mdDECISION_TREE.mdJAVASCRIPT_PATTERNS.md詳細
n8n Code ノード
Code ノードは強力ですが、多くの場合、適切なツールではありません。ORM で済む処理に生の SQL を使うようなものです。実際に必要なケースはありますが、Code ノードが式で実現できるロジックを処理し始めると、ワークフローの可読性、デバッグのしやすさ、保守性が低下します。パフォーマンスにも実質的な差があります。Code はサンドボックス化された JS ランタイムで実行されますが、式と Edit Fields は同一プロセス内で実行されます。また、1 回の呼び出しあたりのオーバーヘッドは、Code のほうが数百倍高くなることがあります(同等のロジックで、体感では約 2ms 対約 600ms)。頻繁に実行される処理やアイテム数が多い場合、この差は積み重なります。
基本方針
-
Code ノードは最後の手段です。 判断の順序は、式(
{{...}})→ Edit Fields 内のアロー関数 → Code ノードです。最初の 2 つの方法で、ほとんどの「このデータを変換する」タスクに対応できます。複数ソースの集約、外部ライブラリの利用、以下で説明するいくつかの特定パターンでは、Code ノードを使う価値があります。 -
デフォルトでは JavaScript を使います。 ユーザーが明示的に Python を希望した場合(「ここでは Python を使って」「Python を使う環境です」、Python コードの貼り付けなど)を除き、JS を記述してください。n8n のほかの機能(式、Edit Fields)はすべて JS であり、JS では厳選されたライブラリの許可リスト(
lodash、crypto、luxon)を利用できます。
判断フロー
Need custom logic?
├── Is it a transformation of one or two fields?
│ └── Expression: {{ $json.foo.toUpperCase() }} or {{ $json.items.map(item => item.name).join(', ') }}
│ Most "just transform this" cases land here.
│
├── Is it multi-line, but pure data shaping (map, filter, reduce, conditional)?
│ └── Edit Fields with arrow function expression. See references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md
│
├── Does it need full statements, multiple data sources, or external libs?
│ ├── Are you SURE the above two don't work?
│ │ └── Re-read the parent. The bar is high.
│ └── Yes, genuinely needs it
│ └── Code node. See references/JAVASCRIPT_PATTERNS.md
│
└── Is it actually two separate transformations stitched together?
└── Use two nodes (Edit Fields → Edit Fields, or Edit Fields → IF). Composability beats one big Code block.
各分岐の例を含む完全な判断ロジックについては、references/DECISION_TREE.md を参照してください。
忘れられがちな、式でできること
Code ノードに頼りがちな一般的な処理でも、式で実現できます。
// ❌ Code node
return { name: $input.first().json.name.toUpperCase() }
// ✅ Expression in Edit Fields, "name" field
{{ $json.name.toUpperCase() }}
// ❌ Code node
const items = $input.first().json.items
return { tags: items.map(item => item.tag).filter(tag => tag).join(', ') }
// ✅ Expression
{{ $json.items.map(item => item.tag).filter(tag => tag).join(', ') }}
// ❌ Code node
const date = new Date($input.first().json.created_at)
return { formatted: date.toISOString().slice(0, 10) }
// ✅ Expression with n8n's date extension
{{ $json.created_at.toDateTime().format('yyyy-MM-dd') }}
式で実現できることの詳細については、n8n-expressions-official スキルを参照してください。
Edit Fields 内のアロー関数でできること
Edit Fields は式を使ってフィールド値を設定します。インラインのアロー関数を使えば、Code ノードを使わずに、複数行にわたるロジックの大半を実現できます。
// In Edit Fields, "summary" field:
{{ (() => {
const items = $json.items
const total = items.reduce((sum, item) => sum + item.price, 0)
const tax = total * 0.08
return `Total: $${(total + tax).toFixed(2)}`
})() }}
「ワンライナーにするには少し複雑すぎるロジック」には、適切なツールです。パターンと書式については、references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md を参照してください。
Code ノードが適切な場合
実際に必要なケースはあります。基準は高めですが、「決して使わない」という意味ではありません。以下は正当なケースです。ためらわずにコードを使いましょう。
データセット全体にわたる複数ソースの集約
ノードが次の処理を必要とする場合です。
- 複数の上流ノードを同時に読み取る(例:
$('Source A').all()、$('Source B').all()、$('Source C').first().json)。 - すべてのアイテムを一度に対象として(アイテムごとではなく)、統計や変換を計算する。
- 中間データ構造(ルックアップマップ、アキュムレーター、比率)を用いた複数ステップのロジックを適用する。
最も一般的な正当なケースです。例:
- 分析の集計:グループごとの平均、パーセンタイルによるスコアリング、カテゴリ間の正規化。
- あるソースからルックアップテーブルを作成し、別のソースの行と結合する。
- 2 つの参照データセット間でオフセットや比率を計算し、それを 3 つ目のデータセットに適用する。
// Real-world shape: aggregate test results from one source,
// model metadata from another, category mapping from a third,
// and produce per-model-per-category averages.
const testResults = $('Get Test Results').all().map(item => item.json)
const models = $('Get Models').all().map(item => item.json)
const categoryMap = $('Get Category Map').first().json.testCategoryMap
const categoryByTestId = Object.fromEntries(
categoryMap.map(mapping => [mapping.testId, mapping.category])
)
const result = models.map(model => {
const modelTests = testResults.filter(test => test.modelId === model.id)
const stats = modelTests.reduce((acc, test) => {
const cat = categoryByTestId[test.testId]
if (!cat) return acc
acc[cat] ??= { scored: 0, available: 0, count: 0 }
acc[cat].scored += test.pointsScored ?? 0
acc[cat].available += test.pointsAvailable ?? 0
acc[cat].count += 1
return acc
}, {})
const averages = Object.fromEntries(
Object.entries(stats).map(([category, stat]) => [
category,
{ avg: stat.available > 0 ? stat.scored / stat.available : 0, n: stat.count }
])
)
return { modelId: model.id, modelName: model.modelName, ...averages }
})
return result.map(json => ({ json }))
技術的には、$('Node Name').all() を使ってアイテムをまたいで参照し、式内で reduce を実行できます。しかし、結合、グループ化、ネストされた集約など、これほど複雑な構造の場合、結果は読みにくくデバッグも不可能な、1 行の巨大な式になります。Code を使いましょう。
外部ライブラリ
JS Code では厳選された許可リスト(lodash など)から require できますが、式ではできません。
必ず最初にネイティブノードがないか確認してください。 n8n には、多くの人が思っている以上に多くのネイティブノードがあります。ネイティブノードで実現できる処理に Code を使うのは、よくある間違いです。続く 2 つの小節では、具体的な注意点を説明します。
暗号処理:Code ではなく Crypto ノードを使う
HMAC、署名、ハッシュ、暗号化には、n8n にネイティブの Crypto ノード(n8n-nodes-base.crypto)があります。 使いましょう。JavaScript を書かなくても、SHA256、MD5、HMAC、暗号化/復号、乱数生成を処理できます。
// WRONG (recurring AI slip):
const crypto = require('crypto')
const hash = crypto.createHash('sha256').update(buf).digest('hex').slice(0, 12)
// RIGHT: configure the Crypto node with operation: 'hash', type: 'SHA256'
// then read $('Hash').item.json.<output> downstream.
require('crypto') を使う Code のパターンは、「Code ノードが必要だ」と誤って判断する、最もよくあるケースのひとつです。必要ありません。Crypto ノードで対応できます。
文字列ではなくバイナリをハッシュする
PDF、画像、ファイルバッファーなどのバイナリをハッシュする必要があるからといって、すぐに Code を使わないでください。Crypto ノードには binaryPropertyName パラメーターがあります。バイナリスロットのキーを指定すれば、バッファーを直接ハッシュできます。ユーザーコードで this.helpers.getBinaryDataBuffer(...) を使う必要はありません。
// WRONG (recurring AI slip with binary):
const crypto = require('crypto')
const buf = await this.helpers.getBinaryDataBuffer($itemIndex, 'data')
const hash = crypto.createHash('sha256').update(buf).digest('hex')
// RIGHT: Crypto node configured to hash binaryPropertyName='data', SHA256.
// Then $('Crypto').item.json.<output> has the hash; chain a Set node for any field shaping.
Crypto ノードを使えない暗号処理で Code が有効なのは、標準的でない署名方式(カスタム AWS 形式の署名など)が必要で、かつ httpCustomAuth 認証情報でも対応できない場合です。まれなケースです。理由を明確に説明してください。
XML/SOAP/RSS の解析:Code ではなく XML ノードを使う
n8n には解析と文字列化の操作を備えたネイティブの XML ノード(n8n-nodes-base.xml)があります。 XML を JSON に変換する機能が組み込まれています。変換後は通常の JSON なので、Edit Fields のアロー関数式で、Code を使って行おうとするフィールド抽出、配列の正規化(Array.isArray(...) ? ... : ...)、リンクの検索(.find())をすべて処理できます。
// WRONG (recurring AI slip):
// XML node already parsed → another Code node to extract a few fields:
const entry = $('Parse XML').item.json.feed.entry
const firstEntry = Array.isArray(entry) ? entry[0] : entry
return { json: { title: firstEntry.title, url: firstEntry.link.find(link => link.type === 'pdf').href } }
// RIGHT: Edit Fields with arrow function expressions:
// title: ={{ (() => { const entry = $('Parse XML').item.json.feed.entry; return Array.isArray(entry) ? entry[0].title : entry.title; })() }}
// pdfUrl: ={{ $('Parse XML').item.json.feed.entry.link.find(link => link.type === 'pdf')?.href }}
インライン式では、複数行のアロー関数を使ってもフィールド抽出のロジックが本当に複雑すぎる場合は、次に使うのは Code ノードではなく、単一の複数行アロー関数を使った Edit Fields です。references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md を参照してください。
これらに共通する点
有効なケースはスコープに関するものです。つまり、データセット全体、複数のソース、または単一アイテム用ツールでは扱えない状態を持つ構成です。無効なケースは、Code が式でできる処理、またはネイティブノードがすでにできる処理を行う場合です。
簡単な確認方法:
- 「この Code ノードの役割を『このアイテムを受け取って……』と説明できるか?」 できるなら、ツールの選択を誤っています。
- 「これに対応するネイティブノードはあるか?」 まず
search_nodesで検索してください。Crypto、XML、JSON 解析、日付計算(Luxon)、HTTP 呼び出し、ファイル入出力、正規表現による照合には、すべてネイティブノードまたは式レベルのサポートがあります。
JavaScript Code ノードの詳細
モードは 2 つあります。
- Run Once for All Items(デフォルト。こちらを使用):
$input.all()を使って 1 回実行されます。アイテムごとの処理が必要な場合は、内部でfor (const item of $input.all())を使ってください。これが標準的な形式であり、ほとんどの場合はこちらが適しています。 - Run Once for Each Item:
$input.first()(または$input.item)を使って、アイテムごとに 1 回実行されます。
一般的な形式:
// Run Once for All Items
const items = $input.all()
const totals = items.map(item => ({
...item.json,
total: item.json.qty * item.json.price,
}))
return totals.map(json => ({ json }))
戻り値は、生の JSON ではなく、{ json: ... } オブジェクト(または { json: ..., binary: ... } オブジェクト)の配列である必要があります。
バイナリの処理、エラーのパターン、Code ノード特有のバグについては、references/JAVASCRIPT_PATTERNS.md を参照してください。
リファレンスファイル
| ファイル | 読むタイミング |
|---|---|
references/DECISION_TREE.md | Code ノードを使おうとしていて、より簡単な方法が本当に使えないか確認したいとき |
references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md | データ整形だけの処理が複数行になるとき |
references/JAVASCRIPT_PATTERNS.md | Code ノードが本当に必要で、言語に JS を使うとき |
アンチパターン
| アンチパターン | 問題点 | 修正方法 |
|---|---|---|
return { x: $input.first().json.x.toUpperCase() } を行う Code ノード | 1 つの式のためにノード全体を使っている | Edit Fields の式に置き換える |
| メール本文用の HTML 文字列を作成する Code ノード | Email ノードの本文フィールドでは式を使用できる | 式をメールノードに直接記述する |
日付のフォーマットに new Date() を使う Code ノード | Luxon の明快さには及ばない | 式で Luxon を使う。n8n-expressions-official を参照 |
| Set ノードと Code ノードの組み合わせ(Set で入力を作成し、Code で変換する) | 1 つで済む処理に 2 つのノードを使っている | 1 つの Edit Fields にまとめ、アロー関数を使う |
| Code ノードのテキストに認証情報やトークンを貼り付ける | テキストフィールドに貼り付けるのと同じ漏えいリスクがある | Code ノードではなく、認証情報を使う |