Back to Blog

n8n Expression Cheat Sheet (2026)

Alex Kim
8 min read
n8n Expression Cheat Sheet (2026)

n8n Expression Cheat Sheet (2026)

Stop Googling the same n8n expressions over and over. This is the reference you'll actually use.

n8n expressions are powerful, but the syntax trips people up constantly. Whether you're formatting dates, building conditional logic, or manipulating JSON, this cheat sheet covers what you need.

Bookmark this. You'll be back.


Quick reference: The essentials

Here's what 90% of your expression work looks like:

// Access the current item
{{ $json.fieldName }}

// Access data from a specific node
{{ $node["Node Name"].json.fieldName }}

// Current timestamp
{{ $now }}

// Conditional (ternary)
{{ $json.status === "active" ? "Yes" : "No" }}

Datetime expressions with Luxon

n8n uses Luxon for datetime handling. Forget JavaScript's messy Date object. Luxon just works.

Getting the current time

// Current datetime (ISO format)
{{ $now.toISO() }}
// Output: 2026-01-30T14:30:00.000-08:00

// Just the date
{{ $now.toISODate() }}
// Output: 2026-01-30

// Just the time
{{ $now.toISOTime() }}
// Output: 14:30:00.000-08:00

// Unix timestamp (seconds)
{{ $now.toSeconds() }}
// Output: 1738275000

// Unix timestamp (milliseconds)
{{ $now.toMillis() }}
// Output: 1738275000000

Formatting dates

The toFormat() method is your best friend:

// Custom format
{{ $now.toFormat("yyyy-MM-dd") }}
// Output: 2026-01-30

// US style
{{ $now.toFormat("MM/dd/yyyy") }}
// Output: 01/30/2026

// Human readable
{{ $now.toFormat("MMMM d, yyyy") }}
// Output: January 30, 2026

// With time
{{ $now.toFormat("yyyy-MM-dd HH:mm:ss") }}
// Output: 2026-01-30 14:30:00

// 12-hour format
{{ $now.toFormat("h:mm a") }}
// Output: 2:30 PM

Format tokens reference

TokenOutputExample
yyyy4-digit year2026
yy2-digit year26
MMMonth (padded)01
MMonth1
MMMMMonth nameJanuary
MMMMonth abbrevJan
ddDay (padded)30
dDay30
HHHour 24h (padded)14
hHour 12h2
mmMinutes30
ssSeconds00
aAM/PMPM
EEEEDay nameThursday
EEEDay abbrevThu

Date math

Add or subtract time easily:

// Add days
{{ $now.plus({ days: 7 }).toISODate() }}
// Output: 2026-02-06

// Subtract hours
{{ $now.minus({ hours: 2 }).toISO() }}

// Multiple units
{{ $now.plus({ months: 1, days: 15 }).toISODate() }}

// Start of day
{{ $now.startOf("day").toISO() }}
// Output: 2026-01-30T00:00:00.000-08:00

// End of month
{{ $now.endOf("month").toISODate() }}
// Output: 2026-01-31

Working with timezones

// Convert to specific timezone
{{ $now.setZone("America/New_York").toISO() }}

// Convert to UTC
{{ $now.toUTC().toISO() }}

// Get timezone name
{{ $now.zoneName }}
// Output: America/Los_Angeles

Parsing date strings

// From ISO string
{{ DateTime.fromISO($json.dateField).toFormat("MM/dd/yyyy") }}

// From custom format
{{ DateTime.fromFormat($json.dateField, "dd-MM-yyyy").toISO() }}

// From Unix timestamp (seconds)
{{ DateTime.fromSeconds($json.timestamp).toISO() }}

// From Unix timestamp (milliseconds)
{{ DateTime.fromMillis($json.timestampMs).toISO() }}

Conditional logic (ternary operators)

The ternary operator is how you do if/else in expressions:

// Basic syntax: condition ? valueIfTrue : valueIfFalse

// Simple check
{{ $json.status === "active" ? "Active" : "Inactive" }}

// Null/undefined check
{{ $json.name ? $json.name : "Unknown" }}

// Shorter null check (nullish coalescing)
{{ $json.name ?? "Unknown" }}

// Nested conditions (use sparingly)
{{ $json.score > 90 ? "A" : $json.score > 80 ? "B" : "C" }}

// Check if field exists
{{ $json.email !== undefined ? "Has email" : "No email" }}

// Empty string check
{{ $json.name !== "" ? $json.name : "No name provided" }}

Common patterns

// Boolean to Yes/No
{{ $json.isEnabled ? "Yes" : "No" }}

// Pluralization
{{ $json.count === 1 ? "item" : "items" }}

// Default values
{{ $json.priority ?? "medium" }}

// Conditional formatting
{{ $json.amount > 0 ? "+" + $json.amount : $json.amount }}

JSON manipulation

Accessing nested data

// Dot notation
{{ $json.user.profile.name }}

// Bracket notation (required for special characters)
{{ $json["user-data"]["first-name"] }}

// Array access
{{ $json.items[0].name }}

// Last item in array
{{ $json.items[$json.items.length - 1].name }}

Array operations

// Get array length
{{ $json.items.length }}

// Map to extract field
{{ $json.items.map(item => item.name) }}

// Filter array
{{ $json.items.filter(item => item.active === true) }}

// Find first match
{{ $json.items.find(item => item.id === "123") }}

// Join array to string
{{ $json.tags.join(", ") }}

// Check if array includes value
{{ $json.roles.includes("admin") ? "Is admin" : "Not admin" }}

Object operations

// Get all keys
{{ Object.keys($json.data) }}

// Get all values
{{ Object.values($json.data) }}

// Check if key exists
{{ "email" in $json ? "Has email" : "No email" }}

// Spread into new object (in Function node)
{{ { ...$json, newField: "value" } }}

String manipulation

Basic operations

// Uppercase
{{ $json.name.toUpperCase() }}

// Lowercase
{{ $json.name.toLowerCase() }}

// Trim whitespace
{{ $json.input.trim() }}

// Replace text
{{ $json.text.replace("old", "new") }}

// Replace all occurrences
{{ $json.text.replaceAll("old", "new") }}

// Split to array
{{ $json.csv.split(",") }}

// Get substring
{{ $json.text.substring(0, 10) }}

// Check if includes
{{ $json.text.includes("keyword") }}

// Check if starts with
{{ $json.text.startsWith("http") }}

Template literals

Build strings with embedded expressions:

// Basic interpolation
{{ `Hello, ${$json.name}!` }}

// Multi-part string
{{ `${$json.firstName} ${$json.lastName}` }}

// With formatting
{{ `Order #${$json.orderId} - Total: $${$json.total.toFixed(2)}` }}

Accessing other nodes

Previous node data

// Input data (same as $json in most cases)
{{ $input.item.json.fieldName }}

// All items from input
{{ $input.all() }}

// First item
{{ $input.first().json.fieldName }}

// Last item
{{ $input.last().json.fieldName }}

Specific node by name

// Single field
{{ $node["HTTP Request"].json.data.id }}

// Check if node has data
{{ $node["Webhook"].json ? "Has data" : "No data" }}

// All items from node
{{ $("Node Name").all() }}

// First item from node
{{ $("Node Name").first().json.fieldName }}

Workflow context

// Workflow ID
{{ $workflow.id }}

// Workflow name
{{ $workflow.name }}

// Execution ID
{{ $execution.id }}

// Execution mode (manual, trigger, etc.)
{{ $execution.mode }}

// Current item index
{{ $itemIndex }}

// Run index (for loops)
{{ $runIndex }}

Number operations

// Round to 2 decimal places
{{ $json.price.toFixed(2) }}

// Round down
{{ Math.floor($json.value) }}

// Round up
{{ Math.ceil($json.value) }}

// Round to nearest
{{ Math.round($json.value) }}

// Absolute value
{{ Math.abs($json.difference) }}

// Parse string to number
{{ parseInt($json.stringNumber) }}

// Parse to float
{{ parseFloat($json.stringDecimal) }}

// Random number (0-1)
{{ Math.random() }}

// Random integer (1-100)
{{ Math.floor(Math.random() * 100) + 1 }}

Common pitfalls and fixes

Problem: Expression returns [object Object]

Cause: You're trying to output an object as a string.

Fix: Access a specific field or use JSON.stringify():

// Wrong
{{ $json.user }}

// Right
{{ $json.user.name }}

// Or stringify if you need the whole object
{{ JSON.stringify($json.user) }}

Problem: Cannot read property of undefined

Cause: The field doesn't exist or a parent is null.

Fix: Use optional chaining or check for existence:

// Wrong
{{ $json.user.profile.name }}

// Right (optional chaining)
{{ $json.user?.profile?.name ?? "Unknown" }}

// Or explicit check
{{ $json.user && $json.user.profile ? $json.user.profile.name : "Unknown" }}

Problem: Date showing as Invalid DateTime

Cause: Wrong format when parsing.

Fix: Match the format exactly:

// If your date is "30-01-2026"
{{ DateTime.fromFormat($json.date, "dd-MM-yyyy").toISO() }}

// If your date is "2026/01/30"
{{ DateTime.fromFormat($json.date, "yyyy/MM/dd").toISO() }}

// When in doubt, use ISO
{{ DateTime.fromISO($json.date).toISO() }}

Problem: Ternary not working as expected

Cause: JavaScript truthy/falsy confusion.

Fix: Be explicit about the condition:

// Wrong (0 is falsy, empty string is falsy)
{{ $json.count ? "Has items" : "Empty" }}

// Right
{{ $json.count > 0 ? "Has items" : "Empty" }}
{{ $json.name !== "" ? $json.name : "No name" }}

Problem: Expression not updating

Cause: Referencing a node that runs after the current one.

Fix: Check your workflow order. You can only access data from nodes that have already executed.


Quick copy-paste templates

Timestamp for filenames

{{ $now.toFormat("yyyyMMdd_HHmmss") }}
// Output: 20260130_143000

Slack-formatted date

{{ `<!date^${$now.toSeconds()}^{date_short} at {time}|${$now.toISO()}>` }}

Email greeting by time of day

{{ $now.hour < 12 ? "Good morning" : $now.hour < 17 ? "Good afternoon" : "Good evening" }}

Clean phone number

{{ $json.phone.replace(/[^0-9]/g, "") }}

Generate UUID-like string

{{ $now.toMillis().toString(36) + Math.random().toString(36).substring(2) }}

More resources


Need help with complex workflows? Book a call or join our community.

#n8n#Automation#Expressions
Available for new projects

Ready to Ship?

Let's talk about what automation could do for your business. No sales pitch. Just a real conversation about your challenges and whether we're a good fit.

30-minute call. No commitment. We'll tell you honestly if we can help.