FlowKit

Le node Code de n8n : maîtriser les expressions et JavaScript pour manipuler les données

Publié le 21 juillet 2026 · 6 min de lecture

n8n propose deux façons de manipuler des données : les expressions, disponibles dans n'importe quel champ de n'importe quel node, et le node Code, qui exécute du JavaScript complet. Confondre les deux mène soit à des expressions illisibles qui tentent de faire trop, soit à des nodes Code sortis d'un canon pour un simple formatage de date. Comprendre où tracer la ligne — et maîtriser le format items sous-jacent — change la vitesse à laquelle on construit un workflow qui marche du premier coup.

Expressions : pour une valeur, dans un champ

Une expression n8n s'écrit entre doubles accolades {{ }} directement dans un champ — un node Set, un paramètre d'URL, un header HTTP. Elle a accès aux mêmes variables globales que le node Code : $json pour l'item courant, $node["NomDuNode"].json (ou la forme raccourcie $('NomDuNode')) pour accéder à un node précédent par son nom, $now, $workflow, etc.

{{ $json.email.toLowerCase() }}
{{ $node["Get Customer"].json.name }}
{{ $now.minus({ days: 7 }).toISO() }}

Les expressions supportent une bonne partie de la syntaxe JavaScript (méthodes de chaînes, ternaires, accès à des tableaux), ce qui pousse parfois à les empiler dans un seul champ jusqu'à obtenir une ligne illisible. La limite pratique : dès qu'une expression a besoin d'une variable intermédiaire, d'une boucle, ou d'une condition à plusieurs branches, c'est le signal qu'il faut basculer sur un node Code plutôt que de continuer à empiler des ternaires imbriqués.

Ce risque n'est pas propre à n8n : une étude de référence de Raymond Panko, publiée dans le Journal of Organizational and End User Computing en 1998, a montré qu'une proportion élevée de feuilles de calcul construites par des utilisateurs non-développeurs contiennent des erreurs de logique non détectées, précisément parce qu'une formule s'empile et se complexifie sans les garde-fous d'un vrai langage de programmation (Panko, 1998, Journal of Organizational and End User Computing). Une expression n8n qui s'étire sur plusieurs ternaires imbriqués reproduit exactement ce risque : mieux vaut basculer vers un node Code dès que la logique dépasse la lecture ou la légère transformation d'une valeur unique.

Le format items : la structure que tout node manipule

Entre deux nodes, n8n fait toujours circuler un tableau d'items, chaque item ayant la forme :

{
  json: { /* vos données */ },
  binary: { /* fichiers optionnels : PDF, images... */ }
}

C'est vrai même pour un item unique : un node qui reçoit une seule commande reçoit un tableau d'un seul élément, [{ json: { order_id: 123, ... } }]. Cette contrainte de format est la source n° 1 des erreurs dans un node Code mal écrit : oublier l'enveloppe json en sortie, ou renvoyer un objet au lieu d'un tableau.

Les deux modes du node Code

Le node Code propose un sélecteur en haut du panneau : Run Once for All Items ou Run Once for Each Item. Le choix détermine à la fois l'accès aux données et la forme du retour attendu.

Run Once for All Items

Le code s'exécute une seule fois, avec accès à l'ensemble des items via $input.all(). Vous devez retourner explicitement un tableau d'objets au format { json: {...} }. C'est le mode adapté pour filtrer, agréger, dédupliquer ou réordonner un ensemble d'items — tout ce qui nécessite de « voir » plusieurs items à la fois.

// Filtrer les commandes de plus de 100€ et calculer un total
const items = $input.all();

const highValue = items.filter((item) => item.json.total > 100);

const grandTotal = highValue.reduce((sum, item) => sum + item.json.total, 0);

return highValue.map((item) => ({
  json: { ...item.json, grandTotal }
}));

Run Once for Each Item

Le code s'exécute une fois par item, $json représente directement l'item courant, et le retour se fait de façon plus simple — un objet unique, implicitement enveloppé. Ce mode convient pour une transformation indépendante d'un item à l'autre : normaliser un champ, calculer une valeur dérivée, valider un format.

// Normaliser un email et calculer un score simple
const email = ($json.email || "").trim().toLowerCase();
const score = email.endsWith("@gmail.com") ? 1 : 2;

return { json: { ...$json, email, score } };

Boucler sur $input.all() : le pattern le plus courant

La grande majorité des node Code en mode « All Items » suivent le même squelette : récupérer les items, transformer avec .map(), filtrer avec .filter(), agréger avec .reduce().

const items = $input.all();

// Transformer
const withDiscount = items.map((item) => ({
  json: {
    ...item.json,
    priceWithDiscount: item.json.price * 0.9
  }
}));

// Filtrer
const inStock = withDiscount.filter((item) => item.json.stock > 0);

// Agréger
const totalStock = inStock.reduce((sum, item) => sum + item.json.stock, 0);

return inStock;

Ces trois méthodes couvrent l'essentiel des besoins de transformation de données sans jamais écrire de boucle for explicite — plus lisible, et moins sujet aux erreurs d'index.

Accéder aux données d'un node précédent avec $('Nom du Node')

$json ne donne accès qu'à l'item courant issu du node immédiatement précédent. Pour remonter plus loin dans le workflow, $('Nom du Node').all() (ou .first() pour un seul item) récupère les items d'un node spécifique par son nom, quelle que soit sa position :

const customer = $('Get Customer').first().json;
const orders = $('Get Orders').all();

const enriched = orders.map((order) => ({
  json: { ...order.json, customerName: customer.name }
}));

return enriched;

C'est la technique à connaître dès qu'un workflow combine plusieurs sources — typiquement après un node Merge, ou pour croiser une donnée de contexte récupérée tôt dans le workflow (comme dans notre guide sur la connexion de n8n à Supabase) avec le résultat d'un appel plus tardif.

Gérer les erreurs dans le node Code

Un node Code non protégé fait planter l'exécution entière au premier undefined inattendu. Un try/catch explicite permet de décider quoi faire : logguer et continuer, ou renvoyer un item d'erreur exploitable en aval.

const items = $input.all();
const results = [];

for (const item of items) {
  try {
    const parsed = JSON.parse(item.json.rawPayload);
    results.push({ json: { ...item.json, parsed, error: null } });
  } catch (err) {
    results.push({ json: { ...item.json, parsed: null, error: err.message } });
  }
}

return results;

Cette approche — capturer l'erreur par item plutôt que de laisser un seul item corrompu bloquer tout le lot — s'articule bien avec un Error Workflow dédié pour les échecs plus graves ; voir notre article sur la gestion des erreurs dans n8n pour la vue d'ensemble.

Pièges courants

  • Undefined non gardé : item.json.customer.email plante si customer est absent. Préférez l'optional chaining (item.json.customer?.email) ou une valeur par défaut explicite.
  • Types confondus : une valeur venant d'un formulaire ou d'un webhook arrive souvent en chaîne même quand elle représente un nombre ("42" au lieu de 42) ; un Number() ou parseInt() explicite évite des comparaisons qui échouent silencieusement.
  • Mutation d'objets partagés : modifier directement item.json.champ = valeur dans une boucle peut avoir des effets de bord inattendus selon le mode ; préférez le spread ({ ...item.json, champ: valeur }) pour construire un nouvel objet plutôt que de muter l'existant.
  • Oublier l'enveloppe json : retourner { nom: "x" } au lieu de { json: { nom: "x" } } est l'erreur la plus fréquente chez les débutants sur ce node.
  • Mélanger les deux modes mentalement : écrire du code pensé pour « All Items » ($input.all(), retour d'un tableau) alors que le sélecteur est resté sur « Each Item » — ou l'inverse — génère des erreurs de format difficiles à diagnostiquer sans vérifier ce réglage en premier.

En résumé

Les expressions couvrent la lecture et la transformation légère d'une valeur dans un champ ; le node Code prend le relais dès qu'il faut boucler, agréger ou combiner plusieurs sources avec une vraie logique. Maîtriser le format items ({ json, binary }) et le bon mode (All vs Each Item) évite la majorité des erreurs de débutant. Ces briques JavaScript reviennent dans presque tous les workflows un peu avancés — y compris ceux qui découpent une logique complexe en sub-workflows réutilisables ou qui construisent des outils personnalisés pour un AI Agent, où le node Code sert justement à exposer une fonction JavaScript comme outil que le modèle peut appeler.

FAQ

Questions fréquentes

Quand utiliser une expression plutôt qu'un node Code ?

Une expression suffit pour lire ou transformer légèrement une valeur unique dans un champ (concaténer une chaîne, formater une date, faire un calcul simple) sans écrire de logique. Passez au node Code dès que vous devez boucler sur plusieurs items avec une logique conditionnelle, faire des calculs sur un tableau entier, ou combiner des données de plusieurs nodes précédents avec des transformations qui dépassent une simple expression sur une ligne.

Quelle est la différence entre Run Once for All Items et Run Once for Each Item ?

Run Once for All Items exécute le code une seule fois avec accès à tous les items via $input.all(), et vous devez retourner explicitement un tableau d'items en sortie — c'est le mode à utiliser pour filtrer, agréger ou réordonner un ensemble. Run Once for Each Item exécute le code séparément pour chaque item, avec $json représentant directement l'item courant, et retourne implicitement un objet par exécution — plus simple pour une transformation item par item sans dépendance entre eux.

Pourquoi mon node Code renvoie-t-il une erreur sur le format de sortie ?

n8n attend en sortie un tableau d'objets au format { json: {...} }, éventuellement avec une clé binary. Retourner directement un objet ou un tableau de valeurs brutes ({ nom: 'x' } au lieu de { json: { nom: 'x' } }) déclenche une erreur ou un comportement inattendu. Vérifiez systématiquement que chaque élément retourné respecte cette enveloppe { json: ... }.

Comment accéder aux données d'un node plus loin en amont, pas seulement le précédent direct ?

Utilisez $('Nom du Node').all() pour récupérer tous les items d'un node spécifique par son nom, quelle que soit sa position dans le workflow, ou $('Nom du Node').first() pour le premier item seulement. Cela fonctionne dans une expression comme dans un node Code, et évite de devoir faire transiter une donnée à travers tous les nodes intermédiaires juste pour y accéder plus loin.

Bundle FlowKit Complet

269 €