n8n data, expressions and the Code node for marketers
Read and reshape n8n data: items, JSON, expressions, data nodes and short Code node snippets for cleaning leads and campaign data.
n8n passes data as items of JSON. Expressions read values from those items, data nodes reshape them without code, and the Code node handles the rest in a few lines of JavaScript.
- Every item is a JSON object; most nodes run once per item.
- Drag fields from the input panel into a parameter to write expressions for you.
- Prefer data nodes (Set, Filter, IF, Merge, Aggregate) over code for clarity.
- Use the Code node for logic that compares items or needs several lines.
Checked 4 November 2026 (CET) against n8n documentation and the n8n pricing page. n8n ships updates often and node options, plan limits and prices change, so confirm in your own instance and on the pricing page. "Our view" marks MentionX opinion. Ledgerline is a fictional company used for illustration.
01What does an item look like?
An item is a JSON object. A lead from a form webhook might look like this:
{
"name": "Sam Example",
"email": "sam@example.com",
"company": "Example Ltd",
"employees": 120,
"utm_source": "linkedin"
}If ten leads arrive, the next node receives ten items like this. In the editor, the input and output panels show them as a table, JSON or schema. You can drag a field from the input panel into any parameter, and n8n writes the expression for you.
02How do expressions work?
Any parameter can switch from Fixed to Expression. An expression is wrapped in double curly braces and resolves per item. As you type, the preview below the field shows the value for the first item, so you can see mistakes before you run anything.
Two habits prevent most errors:
- Reference fields by the node that created them when a workflow has branches or merges.
$jsonmeans "the item coming into this node", which may not be what you expect after a Merge. - Normalise early. Add a Set node near the start that lower-cases emails, trims names and fills missing values. Every later node can then trust the data.
03When should you use the Code node?
Use it when you need to:
- Compare items with each other, such as ranking leads by score.
- Build a complex text block, such as a weekly report body.
- Parse awkward API responses.
- Do something no data node does.
The Code node has two modes. Run Once for All Items gives you every item at once, which suits sorting, ranking and building summaries. Run Once for Each Item runs per item, which suits per-row transforms.
A short example that drops personal email domains and adds a priority flag:
const free = ['gmail.com','outlook.com','yahoo.com','hotmail.com'];
return $input.all()
.filter(i => !free.includes(i.json.email.split('@')[1]))
.map(i => ({ json: { ...i.json, priority: i.json.employees > 200 ? 'high' : 'normal' } }));The node must return an array of objects with a json key. That shape is the most common Code node mistake.
Our view: AI assistants such as Claude and ChatGPT are good at writing short n8n Code node snippets if you paste a sample input item and describe the output you want. Always test on pinned data before trusting it.
04Binary data, briefly
Files such as PDFs, images and CSVs travel as binary data attached to items. Nodes such as Extract from File and Convert to File move between binary and JSON. You'll meet this when a workflow reads an uploaded CSV of event attendees or saves a report as a file. For most marketing workflows, keep data in JSON for as long as possible.
05Expressions you'll reuse
| You want | Expression | ||
|---|---|---|---|
| A field from the current item | {{ $json.email }} | ||
| A nested field | {{ $json.company.domain }} | ||
| A field from a specific earlier node | {{ $('Webhook').item.json.body.email }} | ||
| Lower-case and trim | {{ $json.email.toLowerCase().trim() }} | ||
| The email's domain | {{ $json.email.split('@')[1] }} | ||
| Today's date as ISO | {{ $now.toISO() }} | ||
| A fallback when empty | `{{ $json.company | 'Unknown' }}` | |
| Yes/no from a condition | {{ $json.employees > 200 ? 'enterprise' : 'smb' }} |
Expressions are JavaScript inside double curly braces, with n8n helpers such as $json, $now and $('Node name'). They're fine for one-liners. Anything longer belongs in a Code node.
06Data nodes that save you writing code
- Edit Fields (Set): add, rename or remove fields. Use it to give fields stable names early in a workflow.
- Filter: keep only items that match conditions.
- IF and Switch: route items down different branches.
- Merge: bring branches back together, or combine data from two sources by a matching field.
- Aggregate and Split Out: turn many items into one list, or one list into many items.
- Remove Duplicates: drop repeats within one run or compared with earlier runs (lesson 13).
- Date & Time: format and shift dates without code.
A good rule: if a data node can do it, use the data node. Colleagues who don't read JavaScript can still understand the workflow.
07Expression patterns marketers use most
| Need | Pattern | ||
|---|---|---|---|
| Field from current item | {{ $json.email }} | ||
| Field from an earlier node | {{ $('Get lead').item.json.company }} | ||
| Default when empty | `{{ $json.country | 'Unknown' }}` | |
| Lowercase an email | {{ $json.email.toLowerCase() }} | ||
| Email domain | {{ $json.email.split('@')[1] }} | ||
| Today as ISO date | {{ $now.toISODate() }} | ||
| Seven days ago | {{ $now.minus({days: 7}).toISODate() }} |
08When to reach for the Code node
Use the Edit Fields (Set), IF, Switch, Filter, Sort, Aggregate and Summarize nodes first. They're visible to non-coders and easier to maintain. The Code node fits when you need loops over nested data, several calculations at once, or logic that would take five or more nodes.
Keep Code nodes short, comment what they do, and return items in the shape n8n expects: a list of objects with a json key. If AI writes the code for you, test it on pinned data with edge cases before trusting it.
09Worked example: Ledgerline's lead cleaning step
Ledgerline is a fictional accounts-payable software company. Details are illustrative.
Ledgerline's demo form allowed free-text company names and any email address. Sales complained about duplicates and personal emails in the CRM.
The team added a "Normalise lead" Set node to every lead workflow: lower-cased email, trimmed name, a domain field and a segment based on employee count. A Code node dropped free-mail domains into a separate branch that posted to a low-priority Slack channel rather than deleting them, because some genuine prospects use personal email.
The result was fewer junk records and one place to change the rules.
Walkthrough
- Create a workflow with a manual trigger and a Code node that returns three sample leads (copy the shape from the snippet above, with names, emails and employee counts).
- Add an Edit Fields (Set) node. Add
email_domainwith{{ $json.email.split('@')[1] }}andsegmentwith the enterprise/smb expression from the table. - Add a Code node in "Run Once for All Items" mode that drops free-mail domains (gmail.com, outlook.com and similar).
- Add a Switch node routing by
segment. - Run the workflow and check item counts on each branch.
- Rename every node to say what it does, such as "Add segment" and "Drop free-mail".
10Try it yourself
Take a real export of 20 leads (or invent 20 test rows; never use real customer data in a sandbox). Build the workflow above. Then break it on purpose: add a row with no email. Fix the expressions so the workflow handles it with a fallback rather than failing.
11Quick quiz
1. What does $json refer to?
Answer: The JSON data of the current item.
2. Which Code node mode should you use to compare items to each other?
Answer: Run Once for All Items.
3. Can you use the Code node to read data tables directly?
Answer: No. The data tables docs say the Code node can't access them directly; use the Data table node.
12What should you check before the next lesson?
- You can write an expression with a fallback.
- You know the two Code node modes.
- You normalise data near the start of a workflow.
Next: Google Sheets and Slack workflows. Or return to the n8n for Marketers track.
13Common questions
Do I have to learn JavaScript? Only a little. Expressions are one-liners, and data nodes cover most cleaning without code.
Can the Code node use Python? The Code node supports JavaScript and Python. Check your instance, as Python support depends on version and setup.
Why is my expression showing [undefined]? The field name or path is wrong, or the item doesn't have that field. Check the input panel.
Questions people ask
3 answersDo I have to learn JavaScript?
+
Only a little. Expressions are one-liners, and data nodes cover most cleaning without code.
Can the Code node use Python?
+
The Code node supports JavaScript and Python. Check your instance, as Python support depends on version and setup.
Why is my expression showing [undefined]?
+
The field name or path is wrong, or the item doesn't have that field. Check the input panel.
Sources
- n8n Docs, Work with nodesdocs.n8n.io
- n8n Docs, Data tablesdocs.n8n.io
- n8n Docs, Remove Duplicates nodedocs.n8n.io
- n8n Docs, Code nodedocs.n8n.io
- n8n Docs, Expression referencedocs.n8n.io
- All accessed 4 Nov 2026.