Home / Software / n8n / n8n Expressions Cheat Sheet: Variables, Functions and Syntax

n8n Expressions Cheat Sheet: Variables, Functions and Syntax

n8n Expressions Cheat Sheet: Variables, Functions and Syntax

n8n expressions let you insert dynamic values into any workflow field — pulling data from previous nodes, transforming strings, calculating dates, and applying logic without a full Code node. Expressions use double-curly-brace syntax: {{ }}. Inside those braces you write standard JavaScript, with access to a set of n8n-specific variables. Use expressions for inline transformations and simple conditionals; switch to a Code node when logic spans multiple lines, requires loops, or needs external modules.

Expression Syntax Basics

Any field with the expression toggle (the = icon) accepts an expression. The content inside {{ }} is evaluated as JavaScript at runtime. You can reference the current item, other nodes, workflow metadata, and built-in helpers.

Syntax What it does Example
{{ $json.fieldName }} Access a field from the current input item {{ $json.email }}
{{ $json["field name"] }} Access a field with spaces or special characters in the key {{ $json["First Name"] }}
{{ $node["Node Name"].json.field }} Access output data from a specific node by name {{ $node["HTTP Request"].json.id }}
{{ $input.item.json.field }} Access the current item’s data (n8n v1+) {{ $input.item.json.status }}
{{ $('Node Name').item.json.field }} Shorthand for accessing a named node’s current item (n8n v1+) {{ $('Set').item.json.name }}
{{ $prevNode.name }} Name of the immediately previous node {{ $prevNode.name }}
{{ $runIndex }} Current run index (0-based), useful in loops {{ $runIndex }}
{{ $itemIndex }} Index of the current item within the batch {{ $itemIndex }}
{{ $now }} Current date and time as a Luxon DateTime object (UTC) {{ $now.toISO() }}
{{ $today }} Today’s date at midnight UTC as a Luxon DateTime object {{ $today.toFormat("yyyy-MM-dd") }}
{{ $vars.variableName }} Access a workflow-level variable set in the Variables panel {{ $vars.apiBaseUrl }}

Built-in Variables

Variable Type Description
$json object The current input item’s JSON data. The most commonly used variable in expressions.
$binary object The current input item’s binary data (files, images, etc.).
$input object Full input object exposing .item, .items, .first(), .last(), and .all().
$input.item object The current item being processed.
$input.all() array All input items as an array.
$input.first() object The first input item.
$input.last() object The last input item.
$items() array All items from a node — legacy syntax still supported. Prefer $input.all() in v1+.
$node object Information about the current node (name, type, etc.).
$prevNode object Previous node’s metadata: .name, .outputIndex, .runIndex.
$workflow object Workflow metadata: .id, .name, .active.
$execution object Execution metadata: .id, .mode, .resumeUrl.
$env object Environment variables configured in n8n instance settings.
$vars object Workflow-level variables defined in the Variables panel.
$secrets object Credentials and secrets store — available on self-hosted n8n only.
$now DateTime Current UTC date and time as a Luxon DateTime object.
$today DateTime Current date at midnight UTC as a Luxon DateTime object.
$runIndex number 0-based index of the current execution run (useful in loop nodes).
$itemIndex number 0-based index of the current item within the batch being processed.

String Functions

All standard JavaScript string methods are available. The examples below assume $json.value holds the string being operated on.

Expression What it does Example result
.toUpperCase() Converts string to uppercase "hello""HELLO"
.toLowerCase() Converts string to lowercase "HELLO""hello"
.trim() Removes leading and trailing whitespace " hello ""hello"
.trimStart() / .trimEnd() Removes whitespace from start or end only " hello ""hello "
.includes("text") Returns true if the string contains the substring "hello world".includes("world")true
.startsWith("text") Returns true if the string begins with the given value "hello".startsWith("he")true
.endsWith("text") Returns true if the string ends with the given value "hello".endsWith("lo")true
.replace("old", "new") Replaces the first occurrence of a substring "aabbaa".replace("a", "x")"xabbaa"
.replaceAll("old", "new") Replaces every occurrence of a substring "aabbaa".replaceAll("a", "x")"xxbbxx"
.split(",") Splits string into an array using a delimiter "a,b,c".split(",")["a","b","c"]
.slice(0, 10) Extracts a substring from index start to end (exclusive) "Hello World".slice(0, 5)"Hello"
.substring(start, end) Extracts a substring; unlike slice, does not accept negative indices "Hello World".substring(6, 11)"World"
.padStart(5, "0") Pads the start of a string to reach the specified length "42".padStart(5, "0")"00042"
.length Number of characters in the string "hello".length5
String(value) Converts any value to its string representation String(42)"42"
JSON.stringify(obj) Serialises an object or array to a JSON string JSON.stringify({a:1})'{"a":1}'
JSON.parse(str) Parses a JSON string into a JavaScript object JSON.parse('{"a":1}'){a: 1}

Number Functions

Expression What it does Example result
parseInt("42") Parses a string to an integer, discarding any decimal part parseInt("42.9")42
parseFloat("3.14") Parses a string to a floating-point number parseFloat("3.14")3.14
Number("42") Converts a value to a number; returns NaN if conversion fails Number("42")42
.toFixed(2) Formats a number to N decimal places, returns a string (3.14159).toFixed(2)"3.14"
Math.round(n) Rounds to the nearest integer Math.round(4.6)5
Math.floor(n) Rounds down to the nearest integer Math.floor(4.9)4
Math.ceil(n) Rounds up to the nearest integer Math.ceil(4.1)5
Math.abs(n) Returns the absolute (non-negative) value Math.abs(-7)7
Math.max(a, b) Returns the largest of the supplied values Math.max(3, 9)9
Math.min(a, b) Returns the smallest of the supplied values Math.min(3, 9)3
Math.random() Returns a random floating-point number between 0 (inclusive) and 1 (exclusive) Math.random()0.482...
isNaN(value) Returns true if the value is Not a Number isNaN("hello")true

Array Functions

Expression What it does
.length Returns the number of items in the array
.join(", ") Joins all array elements into a single string with the given separator
.includes(value) Returns true if the array contains the specified value
.indexOf(value) Returns the index of the first occurrence of the value, or -1 if not found
.map(item => item.name) Transforms each item and returns a new array of the transformed values
.filter(item => item.active) Returns a new array containing only items that pass the test condition
.find(item => item.id === 1) Returns the first item that satisfies the condition, or undefined
.some(item => item.active) Returns true if at least one item passes the test condition
.every(item => item.active) Returns true if all items pass the test condition
.reduce((acc, item) => acc + item.value, 0) Aggregates the array to a single value (e.g. sum, concatenation)
.slice(0, 5) Returns the first N items without modifying the original array
.reverse() Reverses the array in place and returns it
.sort() Sorts array elements as strings by default; pass a comparator for numbers
.flat() Flattens one level of nested arrays into a single array
.concat([...]) Merges another array onto the end, returning a new array
[...arr1, ...arr2] Spread syntax to merge two arrays into a new array

Date and Time (Luxon)

n8n uses the Luxon library for all date and time handling. $now and $today both return Luxon DateTime objects, and DateTime is available globally in expressions for parsing custom formats. All times are UTC unless you apply a timezone offset.

Expression What it returns Example output
$now.toISO() ISO 8601 string with milliseconds "2026-05-11T14:30:00.000Z"
$now.toFormat("yyyy-MM-dd") Formatted date string (ISO date) "2026-05-11"
$now.toFormat("dd/MM/yyyy") UK date format "11/05/2026"
$now.toFormat("HH:mm:ss") 24-hour time string "14:30:00"
$now.toFormat("d MMMM yyyy") Long-form date with full month name "11 May 2026"
$now.toMillis() Unix timestamp in milliseconds 1747051800000
$now.toSeconds() Unix timestamp in seconds 1747051800
$now.plus({days: 7}) DateTime shifted forward by the given duration DateTime 7 days from now
$now.minus({hours: 2}) DateTime shifted back by the given duration DateTime 2 hours ago
$now.startOf("day") Midnight at the start of the current day "2026-05-11T00:00:00.000Z"
$now.endOf("month") Last millisecond of the current month "2026-05-31T23:59:59.999Z"
$now.weekday Day of the week as a number (1 = Monday, 7 = Sunday) 1
$now.day Day of the month 11
$now.month Month number (1–12) 5
$now.year Four-digit year 2026
DateTime.fromISO("2026-05-11") Parses an ISO 8601 string into a Luxon DateTime DateTime object
DateTime.fromMillis(timestamp) Parses a Unix millisecond timestamp into a Luxon DateTime DateTime object
DateTime.fromFormat("11/05/2026", "dd/MM/yyyy") Parses a string in a custom format into a Luxon DateTime DateTime object

Conditional Logic

Use JavaScript conditional operators directly inside expressions for inline branching. These are evaluated at runtime per item.

Pattern Syntax Behaviour
Ternary operator {{ condition ? "yes" : "no" }} Returns the first value if condition is truthy, otherwise the second
Nullish coalescing {{ value ?? "default" }} Returns value unless it is null or undefined, then returns the default
Logical OR fallback {{ value || "fallback" }} Returns the fallback if value is any falsy value (including 0, "", false)
Logical AND guard {{ value && value.field }} Only accesses .field if value is truthy — a safe navigation pattern
Optional chaining {{ value?.field }} Returns undefined instead of throwing if value is null or undefined
Deep optional chaining {{ value?.nested?.deep }} Safely traverses multiple levels without throwing on any missing intermediate value

Real-world conditional examples

{{/* Route based on a status field */}}
{{ $json.status === "active" ? "Send email" : "Skip" }}

{{/* Use a fallback when a name field may be absent */}}
{{ $json.name ?? "Unknown" }}

{{/* Safely access a nested field with an email fallback */}}
{{ $json.user?.email || "no-email@example.com" }}

{{/* Combine nullish coalescing with optional chaining */}}
{{ $json.address?.postcode ?? "Postcode not provided" }}

{{/* Nested ternary — use sparingly for readability */}}
{{ $json.score >= 90 ? "High" : $json.score >= 50 ? "Medium" : "Low" }}

Working with Multiple Items

$json always refers to the current item being processed. To access data from a different node, or from a specific position in a batch, use the node-reference patterns below.

Pattern Expression Use case
Current item field {{ $json.name }} Access any field on the item currently being processed — the most common pattern
Named node — current item {{ $('HTTP Request').item.json.data }} Get the paired item from a specific upstream node
First item of a node {{ $('Set').first().json.value }} When you always need item index 0, regardless of which item is currently processing
Last item of a node {{ $('Set').last().json.value }} When you need the final item from an upstream batch
All items — mapped to a field {{ $('Split Out').all().map(i => i.json.name) }} Collect a single field from every item in a node into an array
Item by index {{ $('Split Out').all()[2].json.name }} Access a specific item by its zero-based position in the batch
Count items in a node {{ $('Split Out').all().length }} Get the total number of items produced by an upstream node

Useful Real-World Expressions

The following expressions are ready to copy into any n8n field that accepts an expression. Each is self-contained.

Dates and times

{{/* Today's date in UK format */}}
{{ $now.toFormat("dd/MM/yyyy") }}

{{/* ISO timestamp for API payloads */}}
{{ $now.toISO() }}

{{/* Add 30 days to a date field and return ISO string */}}
{{ DateTime.fromISO($json.createdAt).plus({days: 30}).toISO() }}

{{/* Format a stored Unix timestamp as a readable UK date */}}
{{ DateTime.fromMillis($json.timestamp).toFormat("dd/MM/yyyy HH:mm") }}

Strings

{{/* Capitalise the first letter of a string */}}
{{ $json.name.charAt(0).toUpperCase() + $json.name.slice(1) }}

{{/* Truncate long text to 100 characters with ellipsis */}}
{{ $json.description.length > 100 ? $json.description.slice(0, 100) + "..." : $json.description }}

{{/* Build a full name from first and last, skipping empty parts */}}
{{ [$json.firstName, $json.lastName].filter(Boolean).join(" ") }}

{{/* Extract domain from an email address */}}
{{ $json.email.split("@")[1] }}

{{/* Pad a number with leading zeros for invoice or reference numbers */}}
{{ String($json.invoiceNumber).padStart(6, "0") }}

Numbers and currency

{{/* Format a number as GBP currency */}}
{{ "£" + Number($json.amount).toFixed(2) }}

{{/* Calculate a percentage */}}
{{ ((($json.completed / $json.total) * 100)).toFixed(1) + "%" }}

{{/* Clamp a value between a min and max */}}
{{ Math.min(Math.max($json.quantity, 1), 100) }}

Arrays and objects

{{/* Check if an array field is non-empty */}}
{{ Array.isArray($json.items) && $json.items.length > 0 }}

{{/* Sum all price values in a line items array */}}
{{ $json.lineItems.reduce((sum, item) => sum + item.price, 0) }}

{{/* Join an array of tags into a comma-separated string */}}
{{ $json.tags.join(", ") }}

{{/* Get distinct values from an array (deduplicate) */}}
{{ [...new Set($json.categories)] }}

Safety and fallbacks

{{/* Safe email fallback when field may be absent */}}
{{ $json.email ?? "unknown@example.com" }}

{{/* Safely access a deeply nested field */}}
{{ $json.order?.customer?.name ?? "Guest" }}

{{/* Return a value only if it passes a type check */}}
{{ typeof $json.count === "number" ? $json.count : 0 }}

Debugging Expressions

Using the expression editor

Click the = toggle on any field to open the expression editor. The panel renders a live preview of the output below the expression as you type, using the actual input data from the last test run of the previous node. The Input tab on the left shows the full $json object available to that field, which is useful for confirming key names before writing an expression.

Inspecting the full input object

{{/* Dump the entire input as a JSON string to inspect its structure */}}
{{ JSON.stringify($json) }}

{{/* Pretty-print with indentation (useful in a Set node's value field) */}}
{{ JSON.stringify($json, null, 2) }}

Common errors and fixes

Error Cause Fix
Cannot read properties of undefined The field or object you are accessing does not exist on the current item Use optional chaining: {{ $json?.fieldName }} or a nullish fallback: {{ $json.fieldName ?? "default" }}
Expression Error with no further detail Syntax error inside the expression Check for mismatched brackets, unclosed quotes, missing operators, or trailing commas
TypeError: .map is not a function You are calling an array method on a value that is not an array Guard with Array.isArray($json.field) ? $json.field.map(...) : []
NaN in output A numeric operation received a string or undefined value Parse explicitly with Number($json.value) or parseFloat($json.value) and guard with isNaN()
Expression returns [object Object] An object is being coerced to a string directly Use JSON.stringify($json.field) or access the specific sub-field you need
Date method not found The date field is a raw string, not a Luxon DateTime object Parse first: DateTime.fromISO($json.dateField).toFormat("dd/MM/yyyy")

Related articles: Proxmox Cheat Sheet: CLI Commands for VMs, LXC and Storage, Git Cheat Sheet: Every Command You Need, Linux Commands Cheat Sheet: Home Lab and Server Reference