$json vs $items() in n8n — the difference that actually matters
If you're new to n8n and mixing these up, here's the short version:
$json is the current item's data in the current context. Use it inside a Code node set to "Run Once for Each Item", or inline in expressions like {{ $json.email }}.
$items() is the old-school way to grab an array of items from a specific node. It still works in a lot of workflows you'll find online, but it's legacy syntax. The modern equivalent is $input.all() inside a Code node, or $('Node Name').all() in expressions — both are more explicit about which node's data you're pulling.
Rule of thumb I use: if I'm working with ONE item, $json. If I need ALL items to loop, aggregate, or compare, $input.all(). I basically never reach for $items() anymore, but it's worth recognizing when you see it in older templates.
Curious if anyone still has a real use case for $items() over $input.all() — haven't run into one myself.