Hai iniziato a costruire flussi e ti serve un “coltellino svizzero” per piccoli adattamenti che i nodi standard non coprono? Il nodo code n8n è il punto in cui puoi inserire JavaScript leggibile, testabile e sicuro per trasformare dati al volo. In questa guida per principianti vedrai quando ha senso usare il nodo Code di n8n rispetto ai nodi preconfezionati, come funziona la struttura dei dati di n8n (item, json, binary), le differenze tra le modalità Run Once For Each Item e Run Once For All Items, e come restituire l’output correttamente (return items). Troverai esempi pratici di trasformazioni dati con il Code node: mappatura campi JSON in automazioni, normalizzazione di payload API, manipolazione di array e oggetti in n8n, deduplica, ordinamento e formattazione date con JavaScript in n8n. Chiuderemo con best practice, errori comuni nel Code node e un mini‑playbook per test e debug del codice in n8n. Obiettivo: darti le basi per integrare piccoli script JS in un workflow n8n con script JS pulito e manutenibile.

📚 Nuovo a n8n? Parti dalla guida completa: cos'è n8n e come funziona.

[IMG: Schermata del nodo “Code” con editor aperto e selettore di modalità in evidenza]


Quando usare (e quando evitare) il nodo Code

A cosa serve e quali problemi risolve

  • Colmare gap tra nodi: quando devi rinominare campi, unire/suddividere valori, fare calcoli semplici o ristrutturare JSON che i nodi di mapping non coprono facilmente.
  • Normalizzazioni leggere: adattare payload di servizi diversi a un formato comune prima di passare a un nodo successivo.
  • Filtri/ordinamenti dinamici: applicare logiche condizionali non banali senza moltiplicare IF e Switch.

Quando preferire i nodi preconfezionati

  • HTTP, file, integrazioni: usa i nodi “HTTP Request”, “Spreadsheet File”, app nodes nativi o trigger. Mantengono logica dichiarativa, retry e sicurezza migliorata rispetto al codice personalizzato.
  • Operazioni complesse/riusabili: se la logica cresce, meglio creare sub‑workflow e pattern riutilizzabili, mantenendo il nodo Code per punti specifici.

Vantaggi e limiti per la manutenzione dei workflow

  • Vantaggi: velocità, flessibilità, potenza del JavaScript in n8n senza uscire dall’editor.
  • Limiti: codice da mantenere (leggibilità, test); evita di concentrare troppa logica in un solo nodo Code, meglio spezzare per responsabilità (SRP).
  • Linea guida: se superi ~40‑60 righe o replichi codice, valuta refactoring in più nodi o sub‑workflow.

[IMG: Diagramma decisionale “Nodi standard vs Code” con esempi tipici]


Concetti fondamentali: struttura dei dati e variabili built‑in

Struttura dati degli item

  • Ogni messaggio che fluisce tra nodi è un item con almeno la proprietà json. La forma tipica è: { json: { … }, binary?: { … } }.
  • I nodi consumano e producono array di item. Capire questo è chiave per definire l’output del Code node (return items).

Variabili/metodi built‑in

  • $json: l’oggetto JSON dell’item corrente in modalità per‑item.
  • $input.all(): recupera tutti gli item in ingresso come array di oggetti { json, binary? }, utile in modalità batch/aggregazione.
  • Espressioni: oltre al codice, ricorda che in n8n puoi referenziare dati con le espressioni {{ … }} in altri nodi; nel Code usi direttamente $json, $input, ecc.

Modalità di esecuzione

  • Run Once For Each Item: il codice gira per ogni item in ingresso. Di solito restituisci un singolo oggetto item (return { json: … }).
  • Run Once For All Items: processi tutti gli item insieme (const all = $input.all()), spesso per aggregazioni, filtri, ordinamenti; restituisci un array di item (return [ { json: … }, … ]).

Differenze di output

  • Per‑item: ritorna un item (oggetto con chiave json). Esempio: return { json: { … } }.
  • Per‑tutti: ritorna un array di item. Esempio: return items; oppure return [{ json: aggregated }].

Esempio base (per‑item, rinominare e calcolare)

// Mode: Run Once For Each Item
const inJson = $json;

return {
  json: {
    id: inJson.id,
    title: String(inJson.name || '').trim(),
    subtotal: Number(inJson.qty || 0) * Number(inJson.price || 0),
    isActive: Boolean(inJson.status === 'active'),
  }
};

Esempio base (all‑items, aggregare)

// Mode: Run Once For All Items
const rows = $input.all().map(i => i.json);
const total = rows.reduce((acc, r) => acc + Number(r.amount || 0), 0);

return [
  { json: { count: rows.length, total, rows } }
];

Modalità e casi pratici: per‑item vs batch

Modalità Run Once For Each Item

  • Quando usarla: trasformazioni locali (rimappare, aggiungere campi, normalizzare).
  • Esempio: normalizzare una lista di ordini in un formato uniforme.
// Mode: Run Once For Each Item
const o = $json;
const parseDate = (s) => {
  const d = new Date(s || '');
  return isNaN(d) ? null : d.toISOString();
};

return {
  json: {
    orderId: o.id,
    customer: (o.customer_name || '').trim(),
    createdAt: parseDate(o.created_at),
    items: Array.isArray(o.items) ? o.items : [],
    amount: Number(o.total || 0),
    currency: (o.currency || 'USD').toUpperCase(),
  }
};

Modalità Run Once For All Items

  • Quando usarla: filtri complessi, deduplica, ordinamenti, raggruppamenti, merging tra array di item.
  • Esempio: filtrare per stato, ordinare per data, limitare a top 50.
// Mode: Run Once For All Items
const arr = $input.all().map(i => i.json);

const filtered = arr.filter(r => r.status === 'published');
filtered.sort((a, b) => new Date(b.publishedAt) - new Date(a.publishedAt));
const top = filtered.slice(0, 50);

// Ritorna come array di item
return top.map(x => ({ json: x }));

Insight: se devi “rimuovere” item (filtrare), usa la modalità All Items: puoi restituire solo i rimasti. In per‑item dovresti restituire un singolo item per ingresso.


Ricette di trasformazione pronte all’uso

1) Rimappare e rinominare campi

// Per-item: mappa alias e imposta default
const s = $json;
return {
  json: {
    id: s.id || s._id,
    name: s.title || s.name || '',
    email: (s.email || '').toLowerCase(),
    tags: (s.tags || []).map(t => String(t).trim()),
  }
};

2) Filtrare e rimuovere duplicati (in batch)

// All-items: filtra e deduplica per email
const rows = $input.all().map(i => i.json);
const seen = new Set();
const out = [];

for (const r of rows) {
  const email = (r.email || '').toLowerCase().trim();
  if (!email || seen.has(email)) continue;
  seen.add(email);
  out.push(r);
}
return out.map(r => ({ json: r }));

3) Formattazione date con JavaScript in n8n

// Per-item: human readable date
const d = new Date($json.publishedAt || '');
const fmt = new Intl.DateTimeFormat('it-IT', { dateStyle: 'medium', timeStyle: 'short' });
return { json: { ...$json, publishedHuman: isNaN(d) ? null : fmt.format(d) } };

4) Raggruppare elementi per chiave (categorie)

// All-items: group by category
const rows = $input.all().map(i => i.json);
const groups = {};
for (const r of rows) {
  const k = r.category || 'Uncategorized';
  (groups[k] ||= []).push(r);
}
return [{ json: { groups } }];

5) Creare campi calcolati (slug)

// Per-item: slug SEO
const slugify = s => String(s || '')
  .toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  .replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
return { json: { ...$json, slug: slugify($json.title) } };

Queste ricette coprono la maggior parte delle trasformazioni dati con il Code node in un workflow n8n con script JS.


Debug, test e qualità del codice

Come testare il nodo e leggere l’output

  • Esegui “Run Once” del workflow e apri il nodo Code per ispezionare gli item in ingresso/uscita.
  • In modalità All Items, verifica sempre la cardinalità (quanti item rientrano/escono).

Debug del codice in n8n

  • Aggiungi log mirati per capire lo stato intermedio (es. grandezze degli array, chiavi calcolate) e rimuovili a fine debug.
  • Usa try/catch per evidenziare errori con messaggi utili.
// All-items: validazione e gestione errori
try {
  const items = $input.all().map(i => i.json);
  if (!Array.isArray(items)) throw new Error('Input non valido');
  // ... trasformazioni
  return items.map(x => ({ json: x }));
} catch (e) {
  throw new Error(`Code node failed: ${e.message}`);
}

Best practice per il Code node

  • Piccole funzioni pure: isola funzioni (parseDate, normalizeEmail) in alto e riusale.
  • Evita mutazioni involontarie: crea nuovi oggetti con spread (…$json) invece di modificare quelli d’ingresso.
  • Tipi coerenti: normalizza numeri (Number()), stringhe (String().trim()) e booleani (Boolean()).
  • Spezza la logica: se il file cresce, dividi in più nodi Code o combina con Set/IF per chiarezza.
  • Documenta: brevi commenti su input atteso/output e casi limite.

Errori comuni nel Code node

  • Restituire il formato sbagliato: ricorda che in per‑item devi tornare un singolo item, in all‑items un array di item.
  • Dimenticare json: l’output va sempre incapsulato in { json: … }.
  • Gestione null/undefined: proteggi gli accessi con fallback.

[IMG: Pannello esecuzione con sezione “Input” e “Output” aperte sul nodo Code]


Limiti, librerie esterne e alternative

Librerie esterne e limiti del Code node

  • Mantieni il codice “vanilla” e vicino al dato: evita di replicare funzioni coperte da nodi (HTTP, file, integrazioni).
  • Se ti serve chiamare servizi esterni, collegalo a un nodo “HTTP Request” a valle o a monte invece di farlo dal codice.
  • Per esigenze più strutturate, preferisci sub‑workflow riutilizzabili con interfacce chiare.

Quando NON usare il Code node

  • Integrazioni complesse e retry: i nodi dedicati gestiscono errori, timeouts, auth, paginazione meglio del codice “a mano”.
  • Logiche di business estese: più leggibilità con nodi multipli o funzioni incapsulate in sub‑workflow.

Manutenzione e leggibilità del codice in n8n

  • Convenzioni di naming per variabili e campi, commenti asciutti, funzioni a responsabilità singola.
  • Testa con dataset reali ridotti e poi scala; aggiungi controlli di tipo e fallback.

Un mini‑workflow completo: normalizza, filtra, invia

Scenario: ricevi prodotti da un’API, normalizzi, filtri quelli “in stock” e invii solo i top 20 per prezzo.

1) HTTP Request → recupera prodotti (array).
2) Code (Run Once For Each Item) → normalizza campi e calcola subtotal.

const p = $json;
return {
  json: {
    id: p.id,
    name: String(p.name || '').trim(),
    price: Number(p.price || 0),
    stock: Number(p.stock || 0),
    category: p.category || 'misc',
  }
};

3) Code (Run Once For All Items) → filtra, ordina, limita.

const arr = $input.all().map(i => i.json);
const filtered = arr.filter(p => p.stock > 0);
filtered.sort((a, b) => b.price - a.price);
const top = filtered.slice(0, 20);
return top.map(p => ({ json: p }));

4) Email/Slack → invia lista formattata.

[IMG: Canvas con HTTP Request → Code (per‑item) → Code (all‑items) → Email]


Quick Takeaways

  • Il nodo Code di n8n è perfetto per piccole trasformazioni, mapping e normalizzazioni dove i nodi standard non bastano.
  • Capisci la struttura dati: item è { json, binary? } e l’output deve rispettarla.
  • Scegli la modalità giusta: Run Once For Each Item per modifiche locali; Run Once For All Items per filtri/ordinamenti/dedup.
  • Restituisci sempre il formato corretto: per‑item un oggetto, per‑tutti un array di item.
  • Mantieni il codice semplice, testabile e documentato; delega integrazioni e retry ai nodi dedicati.
  • Spezza la logica in più nodi e crea sub‑workflow quando la complessità cresce.

Conclusione

Il nodo code n8n ti offre il giusto equilibrio tra potenza e semplicità: abbastanza JavaScript per adattare i dati dove serve, senza sacrificare la struttura low‑code del workflow. Comprendendo bene item/json, le modalità Run Once For Each Item e Run Once For All Items e l’output del Code node (return items), puoi costruire trasformazioni chiare, affidabili e riusabili. Mantieni le cose “vanilla”: evita mutazioni impreviste, normalizza tipi, aggiungi funzioni pure e commenti essenziali. Per integrazioni e chiamate esterne, appoggiati ai nodi dedicati; per logiche estese, spezza in sub‑workflow. Con questi accorgimenti, i marketer possono realizzare rapidamente pipeline pulite, dalla mappatura campi alla deduplica e formattazione, elevando la qualità del dato in ogni automazione. Inizia con le ricette proposte, prova su piccoli dataset e porta in produzione con fiducia: il tuo workflow n8n con script JS farà il salto di qualità.


FAQ

1) Quando conviene usare il nodo Code di n8n?
Quando servono trasformazioni leggere: rinominare campi, normalizzare payload, calcolare valori, filtrare/ordinare array. Per HTTP/integrations usa nodi dedicati; il Code è il “collante” per le trasformazioni dati con JavaScript in n8n.

2) Qual è la differenza tra “Run Once For Each Item” e “Run Once For All Items”?
La prima elabora un item alla volta (return { json: … }); la seconda lavora su tutti gli item insieme (const arr = $input.all()) e deve restituire un array di item (return [{ json: … }, …]).

3) Come accedo ai dati in ingresso nel Code node?
In per‑item usa $json per il record corrente. In all‑items usa $input.all() per ottenere tutti gli item in ingresso come array di oggetti { json, binary? }.

4) Come evito errori tipici (undefined, tipi incoerenti)?
Applica fallback e casting: String().trim(), Number() per numeri, Boolean() per flag. Evita di mutare l’input direttamente: crea nuovi oggetti con spread (…$json).

5) Posso ordinare, filtrare e deduplicare nel Code node?
Sì, in “Run Once For All Items”: filtra con .filter(), ordina con .sort(), deduplica con Set/Map su una chiave (es. email, id) e restituisci un array di item formattati.


Ci dai una mano?

Quale trasformazione vuoi implementare subito con il nodo Code di n8n: mapping campi, dedup o formattazione del tuo payload? Condividi la tua scelta e questo articolo con il team: da un piccolo script può nascere un grande workflow!

Vuoi automazioni AI su misura per la tua azienda?
Scopri la consulenza →