Understanding expressions: mapping $json, $node and items without code

The biggest n8n learning hurdle explained: what items, $json and $node mean and how to map values by drag and drop without code.

Anyone building a workflow in n8n for the first time sooner or later reaches a point where a fixed UI setting is no longer enough: a value needs to come from the previous node, change depending on the input data, or come from a completely different node earlier in the workflow. This is exactly where the biggest learning hurdle begins for many new users, because terms like $json, $node and items suddenly appear, which without explanation look like cryptic code. Yet behind this lies a fairly simple principle, once it is clear how n8n passes data between nodes.

This article explains using concrete examples what an item in n8n really is, how $json and $node relate to each other, and how you map values by drag and drop, without writing a single line of code yourself. It is based on the official n8n documentation on expressions and the internal data structure, as of July 2026.

What is an item in n8n really?

n8n always passes data between nodes as an array of objects, and each individual element in this array is called an item. According to the n8n documentation on the data structure every item has the fixed form `{ json: {...} }`, where the actual payload data always sits under the key json. An example with two items looks like this:

  • Item 1: `{ json: { name: "Anna", plz: "18055" } }`
  • Item 2: `{ json: { name: "Jonas", plz: "23552" } }`

Important for understanding: a node in n8n usually processes each item individually and repeats its configured action for each element in the array. If an HTTP Request node receives two items, it sends two requests by default, one per item. Once you have internalized this, you also understand why expressions in n8n always refer to the item currently being processed and not to the entire list.

$json: accessing the current item

$json is the most frequently used variable in n8n expressions and represents the json data of the item that the current node is processing. $json is a shorthand for $input.item.json, the input item of the current node. If, for example, you want to output the name from the example above in the next node, you write in a text field:

`{{ $json.name }}`

n8n replaces this expression at execution time with the actual value of the respective item, so with two items it would be "Anna" once and "Jonas" once. You can reach nested fields using dot notation, for example `{{ $json.adresse.plz }}`, provided the data is structured accordingly.

$node and $(): getting data from other nodes

As soon as a value should not come from the directly preceding node, but from any other node earlier in the workflow, $json is no longer enough. This is exactly what $node, or its successor $(), is for. In older workflows and tutorials you will often still find the notation `$node["Node-Name"].json.feld`, this syntax is now considered deprecated. The current form, described in the n8n documentation on referencing previous nodes is:

`{{ $('Node-Name').item.json.feld }}`

If you want not only the currently linked item, but specifically the first, last, or all items of a particular node, you additionally have `$('Node-Name').first()`, `$('Node-Name').last()` and `$('Node-Name').all()` available. If you find an old expression written with $node in a workflow, it is worth updating it to the $() notation when you get the chance, so that it also continues to work reliably after future n8n updates.

Example: getting an email address from an earlier form node

Suppose a workflow starts with a form node called "Kontaktformular", which captures an email address among other things. Three nodes later, in an HTTP Request call to a CRM, you need exactly this address again, even if the nodes in between no longer contain any email data themselves. The expression for this is:

`{{ $('Kontaktformular').item.json.email }}`

This way, regardless of what the nodes in between have done with the data, you access the original item from the Kontaktformular node directly.

Mapping without code: drag and drop in n8n

The most convenient way into expressions does not involve typing any code at all. In the input panel of a node, n8n displays the incoming data as a list or table, and each individual field can be dragged directly with the mouse into a parameter field. n8n automatically generates the matching expression from this, for example `{{ $json.fruit }}`, without you needing to know the syntax yourself. According to the n8n documentation on expressions versus data transformation nodes this method is especially worthwhile when you only want to take over a single value from previous data, because n8n shows directly in the preview which specific value will be used at execution time. For operations such as sorting, merging, or removing duplicates, the documentation instead recommends the ready-made data transformation nodes, because these work without any expression at all and are operated through a guided interface.

Typical pitfalls when getting started

  • Confusing an item with the entire list: $json always only returns the current item, never all items at once. Anyone who wants to go through all items needs $input.all() or $('Node-Name').all() and usually some loop logic or a Code node.
  • Outdated $node syntax from old tutorials: Many older tutorials on the web still show $node["Name"].json, which can cause errors in current n8n versions. The expression reference of the documentation instead consistently uses the $() notation.
  • Missing json key with your own code: If you return data yourself in a Code node, you need to make sure that each returned object is wrapped again in `{ json: {...} }`, otherwise n8n reports an error.
  • Expression shows no value: Usually this is because the referenced node has not yet run in this execution path, or the field in the current item is actually empty. A look at the input panel of the affected node clarifies this faster than any troubleshooting in code.

Once you have internalized these four points, you have overcome the biggest entry hurdle in n8n and from then on keep control over your own workflows, even without a developer background. Anyone who, despite this, prefers experienced support when building more complex automations will find at NordFlux's n8n automation an implementation with a fixed price and German data sovereignty.

Frequently asked questions

What is the difference between $json and $input.item?

$json is a shorthand for $input.item.json and directly returns the json data of the current item. $input.item, on the other hand, returns the complete item object including a possible binary key, which is why $json in practice is almost always the shorter and more common way when you only want to access normal field values.

Why do I see $node instead of $() in old workflows?

$node["Name"].json was the original syntax for referencing data from a specific node, but is now considered deprecated. n8n instead recommends the notation $('Name'), which handles renamings and future version changes more reliably. Old workflows with $node mostly continue to work, but should be updated at the next opportunity.

Can I also use $json to access a field from a completely different node?

No, $json always refers only to the item of the directly incoming data stream at the current node. For fields from any other node located earlier in the workflow, you need the notation $('Node-Name').item.json.feldname, as described in the documentation on referencing previous nodes.

Do I always have to type expressions by hand?

No, mostly not. You can drag fields from the input panel directly into a parameter field, n8n automatically generates the matching expression. Typing by hand is worthwhile especially when you want to access data from a more distant node or want to further process the values with methods such as .toUpperCase() or .map().

What happens if an item does not contain the referenced field at all?

Then the expression usually returns undefined or an empty value instead of an error, unless you access a field of a nested object that does not exist itself. In such cases the function $ifEmpty() from the expression reference helps to automatically insert a default value instead of aborting execution.

About NordFlux

NordFlux UG (haftungsbeschränkt)

NordFlux builds digital employees for organisations: automations and AI agents that take over repetitive work. You stay in control.

More about us
Free initial analysis

Concrete questions about automation or AI?

In a free initial analysis we discuss your case directly. No strings attached.

Understanding expressions: $json, $node and items