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 *