n8n Expression Node: Variables, Functions & JMESPath Reference


⚡ n8n Workflow Automation
T3 · Expression Node Reference

n8n Expression Node: Variables, Functions & JMESPath Reference

n8n expressions are dynamic, runtime‑evaluated snippets enclosed in
{{ }} that access data from any node, workflow metadata,
environment variables, or built‑in functions. They resolve on every execution,
pulling the latest values from $json, $node, or
$jmespath() without hardcoding fields. The expression system
provides 58+ built‑in methods and variables for string
manipulation, math, date formatting, array handling, and JSON querying. This
guide covers the core variables, Luxon DateTime library, JMESPath querying,
and advanced patterns like $if(), $vars, and
$secrets for reusable automations.
[1]
[2]

58+
Built‑in Methods & Variables [3]

5
JMESPath Projections [4]

2
Luxon Convenience Vars ($now, $today) [5]

6
Core Context Variables [1]

Expression Variable Description Example Code Node?
{{ $json.field }} Current item field from input {{ $json.email }} ✅ (as $input.item.json.field)
{{ $node["NodeName"].json.field }} Data from any previous node {{ $node["HTTP Request"].json.id }} ✅ (all(), first(), item)
{{ $now }} Current timestamp (Luxon) {{ $now.toISO() }} ✅ (JavaScript only)
{{ $jmespath($json, "query") }} JMESPath JSON query {{ $jmespath($json, "people[*].name") }} ✅ (as _jmespath() in Python)
{{ $vars.myVar }} Workflow‑scoped variable (Enterprise/Pro Cloud) {{ $vars.approvalLimit }}
{{ $secrets.vault.secret }} External vault secret (Enterprise) {{ $secrets.vault.apiKey }}

How do you reference data from other nodes using $json, $node, and $workflow?

Use {{ $json.field }} for the current node’s input item.
To read output from any preceding node, use
{{ $node["Node Name"].json.field }}. The
$workflow object provides metadata like workflow ID, name,
and the active environment. These variables are evaluated dynamically at
execution time by the WorkflowDataProxy class.
[1]
[6]

$node accepts the node’s display name in double quotes and
supports .all(), .first(), .last(),
.item, and .params. For the current node, use
$node.name and $node.type. $workflow
exposes .id, .name, and .active.
For execution context, $execution provides .id
and .mode (test or production). For execution health checks,
$resumeWebhookUrl (deprecated from 1.85.0) can still be
referenced in legacy workflows but should be replaced by the Wait node
with resume URL support. For the complete reference of every
built‑in variable and method available in the expression editor versus
the Code node, see the
Core n8n Nodes guide.

What are the most useful n8n built‑in methods, variables, and data transformation functions?

n8n provides 58+ built‑in methods and variables
spanning string operations ($json.field.length,
.toUpperCase()), math ({{ 1 + 2 }},
Math.round()), boolean logic ({{ true && false }}),
array handling ([1,2,3][0]), and object access
({ a: 1 }.a). All standard JavaScript operators work
inside expressions. The built‑in function
$if(condition, valueIfTrue, valueIfFalse) provides inline
conditional logic without an IF node.
[3]
[1]

Key methods include: $now and $today for date
handling (Luxon objects with full method chains);
$jmespath(object, searchString) for JSON querying;
$if(condition, trueValue, falseValue) for inline
conditionals; $('NodeName').all() and .first()
for node‑specific data access; $itemIndex (0‑based)
and $runIndex for loop tracking; $workflow.name
and $execution.mode for metadata; $render()
and $evaluateExpression() for template rendering;
$('Webhook').params.paramName for webhook URL parameters;
and $now.plus({days: 7}).toFormat('yyyy-MM-dd') for date
arithmetic. All data transformation functions are only available in the
expressions editor—they are not available in the Code node. For the
complete code‑node–only functions, see the
n8n Code Node transformation examples.

⚡ Expression vs. Code Node Availability: Data
transformation functions (string manipulation, date formatting,
$jmespath()) are available in the expression editor
only—not in the Code node. The Code node provides raw
$input.all(), $json, and
$itemIndex for JavaScript/Python logic but must
implement transformations manually.
[3]

How do you extract and transform nested JSON data with JMESPath expressions in n8n?

n8n provides the $jmespath() function to query and filter
JSON using the JMESPath language. The first argument is the target JSON
object (usually $json), and the second is a JMESPath query
string. Syntax: {{ $jmespath($json, "items[?age>`18`].name") }}.
JMESPath supports five projection types—list, slice, object, flatten,
and filter—that handle nested API responses.
[4]
[7]

Important: n8n uses the JMESPath JavaScript library which follows the
search(object, searchString) parameter order—the opposite
of the JMESPath specification’s search(searchString, object).
When adapting examples from official JMESPath documentation, swap the
argument order [4].
For Python users, _jmespath(object, searchString) is
available in the Code node. Common query patterns: extract all names
(people[*].name), filter by age
(people[?age>`18`]), get first item
(people[0]), extract specific fields
(people[*].[name, age]), and count matches
(length(people[?age>`18`])). For direct bracket‑notation
access (e.g., $json['body']['city']), which eliminates
the need for JMESPath for simple field extraction, see the
n8n Webhook Node Configuration guide.

How do you format dates and times using n8n’s Luxon DateTime expressions?

n8n globally exposes the Luxon DateTime library through$now and
$today convenience variables. $now returns the
current timestamp; $today returns midnight of the current
day. Both are Luxon DateTime objects that support the full method chain:
{{ $now.plus({days: 7}).toFormat('yyyy-MM-dd') }}. Parse
strings with DateTime.fromISO('2019-06-23') or
DateTime.fromFormat("23-06-2019", "dd-MM-yyyy").
[5]
[8]

Key Luxon methods available in expressions: toISO(),
toFormat(), toISODate(), plus(),
minus(), diff(), setZone(),
toRelative(), isValid, year,
month, day, hour,
minute, second, weekday,
startOf('month'), endOf('year').
Always use Luxon’s DateTime() rather than vanilla
JavaScript’s Date()—n8n-specific features like
workflow‑specific timezone settings only work with Luxon.
For timezone control, the instance‑levelGENERIC_TIMEZONE and
the workflow‑level Timezone setting determine the reference timezone for
all Luxon operations [8].
For Python Code node users, Luxon convenience variables are available
but with limited functionality—Python equivalents like
datetime.fromtimestamp() should be used for arithmetic.
For comprehensive date‑based conditional logic patterns, such as
checking order age before triggering actions, see the
IF & Switch node branching guide.

⏱️ Luxon Quick Reference:
{{ $now.toISO() }} → ISO 8601 string.
{{ $now.toFormat('yyyy-MM-dd') }} → custom format.
{{ $now.plus({days: 7, hours: 3}).toISO() }} → date
arithmetic. {{ $now.setZone('America/New_York').toFormat('HH:mm') }}
→ timezone conversion. Always parse strings explicitly with
DateTime.fromFormat() rather than relying on implicit
parsing.

How do you use $vars and $secrets for workflow variables and external vault secrets?

$vars accesses custom variables defined in the
Variables tab (available on Self‑hosted Enterprise and Pro Cloud
plans). Reference with {{ $vars.myVariable }}.
Variables are read‑only during workflow execution and always stored
as strings—n8n replaces the expression with the variable value at
runtime. When a project‑scoped variable shares a key with a global
variable, the project‑scoped value takes precedence.
[9]
[2]

$secrets retrieves secrets from external vault
providers using the syntax
{{ $secrets.<vault-name>.<item-title>.<field-label> }}.
This is an Enterprise plan feature for accessing 1Password, AWS
Secrets Manager, Azure Key Vault, GCP Secret Manager, or HashiCorp
Vault at runtime [2].
Variables accept only alphanumeric characters and underscores (A‑Z,
a‑z, 0‑9, _) with a 50‑character key limit and 1,000‑character
value limit. If a variable has no value, n8n treats it
as undefined—workflows do not automatically fail.
For the complete credential management strategy covering OAuth2
and vault configuration, see the
n8n Credential Nodes guide.

How do you debug n8n expressions and avoid common evaluation errors?

The Expression Editor provides real‑time preview: expand
the editor and click Refresh to see the resolved value against actual
execution data. Auto‑completion surfaces available data paths from
previous node outputs. If an expression returns
[undefined], the referenced field does not exist—use
{{ $if($json.field, $json.field, "N/A") }} for
fallback values. The editor validates syntax and flags errors
before execution [2].

Common pitfalls: mismatched braces (always pair
{{ and }}), undefined fields (use
$if() for fallback), bracket notation for
special characters
($json["field-with-dash"]),
JMESPath argument order reversal (n8n uses
search(object, searchString), not
search(searchString, object)), and accessing
linked item data
(use $("NodeName").item instead
of .first() for linked chains). The expression
evaluation pipeline follows a multi‑stage process: WorkflowDataProxy
resolves context variables, then the engine evaluates JavaScript
code, and error handling provides descriptive messages for
debugging. To validate data structure, use the Schema tab in
the output panel or a Code node with console.log().
For the complete error handling and retry patterns that catch
expression‑related failures, see the
n8n Error Handling nodes guide.

References

This guide is for informational purposes only. For the most current and authoritative information,
always refer to the official n8n website (n8n.io) and
the n8n documentation. Built‑in methods, variable
availability, and enterprise feature requirements may change over time.



Leave a Reply

Your email address will not be published. Required fields are marked *