All posts
Nodox Team··12 min read

n8n Expressions Explained: The Complete Guide to Data Manipulation

Master n8n expressions for data access, transformation, and manipulation. Learn syntax, common patterns, and real-world examples.

n8nexpressionsdata-transformationtutorialreference

Expressions are the secret weapon of n8n power users.

They let you access data, transform values, and build dynamic workflows without writing code. But the syntax trips up everyone at first.

Here's everything you need to know about n8n expressions.

What Are Expressions?

Expressions are dynamic values enclosed in {{ }}. They're evaluated at runtime using data from previous nodes.

Instead of hardcoding:

```

Hello, John

```

You write:

```

Hello, {{ $json.firstName }}

```

And it becomes "Hello, John" when the workflow runs.

Basic Syntax

Accessing Current Node Data

```

{{ $json.fieldName }}

```

$json refers to the input data of the current node.

Nested Objects

```

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

```

Arrays

```

{{ $json.items[0] }} // First item

{{ $json.items[0].name }} // First item's name

{{ $json.items.length }} // Number of items

```

Previous Node Data

```

{{ $('NodeName').item.json.field }}

```

Access data from any previous node by name.

Essential Variables

$json

The current item's data. Most commonly used.

```

{{ $json.email }}

{{ $json.order.total }}

```

$input

All input data to the current node.

```

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

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

{{ $input.all() }} // All items as array

```

$('NodeName')

Reference a specific node's output.

```

{{ $('HTTP Request').item.json.data }}

{{ $('Get Users').first().json.users }}

```

$node

Current node information.

```

{{ $node.name }} // Current node's name

{{ $node.outputIndex }} // Which output (for multi-output nodes)

```

$workflow

Workflow metadata.

```

{{ $workflow.id }}

{{ $workflow.name }}

{{ $workflow.active }}

```

$execution

Current execution details.

```

{{ $execution.id }}

{{ $execution.mode }} // "manual" or "trigger"

{{ $execution.resumeUrl }} // For wait nodes

```

$now / $today

Date/time helpers.

```

{{ $now }} // Current datetime

{{ $today }} // Today at midnight

{{ $now.toISO() }} // ISO format string

{{ $now.minus({days: 7}) }} // 7 days ago

```

Data Type Conversions

To String

```

{{ String($json.number) }}

{{ $json.number.toString() }}

{{ $json.number + '' }}

```

To Number

```

{{ Number($json.string) }}

{{ parseInt($json.string) }}

{{ parseFloat($json.string) }}

{{ +$json.string }}

```

To Boolean

```

{{ Boolean($json.value) }}

{{ !!$json.value }}

```

To Array

```

{{ $json.string.split(',') }} // String to array

{{ Array.from($json.iterable) }} // Iterable to array

{{ [$json.item1, $json.item2] }} // Create array

```

String Operations

Concatenation

```

{{ $json.firstName + ' ' + $json.lastName }}

{{ \Hello, \${$json.name}!\ }}

```

Case Conversion

```

{{ $json.text.toLowerCase() }}

{{ $json.text.toUpperCase() }}

```

Trimming

```

{{ $json.text.trim() }}

{{ $json.text.trimStart() }}

{{ $json.text.trimEnd() }}

```

Substring

```

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

{{ $json.text.slice(-5) }} // Last 5 chars

```

Replace

```

{{ $json.text.replace('old', 'new') }}

{{ $json.text.replaceAll('old', 'new') }}

```

Split and Join

```

{{ $json.csv.split(',') }} // String to array

{{ $json.array.join(', ') }} // Array to string

```

Check Contents

```

{{ $json.text.includes('keyword') }}

{{ $json.text.startsWith('Hello') }}

{{ $json.text.endsWith('.com') }}

```

Array Operations

Accessing Elements

```

{{ $json.items[0] }} // First

{{ $json.items[$json.items.length - 1] }} // Last

```

Filtering

```

{{ $json.users.filter(u => u.active) }}

{{ $json.orders.filter(o => o.total > 100) }}

```

Mapping

```

{{ $json.users.map(u => u.email) }}

{{ $json.items.map(i => i.name.toUpperCase()) }}

```

Finding

```

{{ $json.users.find(u => u.id === 123) }}

{{ $json.items.findIndex(i => i.name === 'target') }}

```

Reducing

```

{{ $json.orders.reduce((sum, o) => sum + o.total, 0) }}

```

Checking

```

{{ $json.items.some(i => i.urgent) }} // Any match?

{{ $json.items.every(i => i.valid) }} // All match?

{{ $json.items.includes('value') }} // Contains value?

```

Sorting

```

{{ $json.items.sort() }} // Alphabetical

{{ $json.items.sort((a, b) => a.price - b.price) }} // By property

```

Date and Time

n8n uses Luxon for dates. Key operations:

Current Time

```

{{ $now }}

{{ $now.toISO() }}

{{ $now.toFormat('yyyy-MM-dd') }}

```

Formatting

```

{{ $now.toFormat('yyyy-MM-dd') }} // 2026-01-19

{{ $now.toFormat('HH:mm:ss') }} // 14:30:00

{{ $now.toFormat('MMMM d, yyyy') }} // January 19, 2026

{{ $now.toFormat('EEE') }} // Mon

```

Parsing Dates

```

{{ DateTime.fromISO($json.dateString) }}

{{ DateTime.fromFormat($json.date, 'MM/dd/yyyy') }}

```

Date Math

```

{{ $now.plus({days: 7}) }}

{{ $now.minus({hours: 2}) }}

{{ $now.startOf('day') }}

{{ $now.endOf('month') }}

```

Comparisons

```

{{ DateTime.fromISO($json.date) > $now }}

{{ $now.diff(DateTime.fromISO($json.date), 'days').days }}

```

Conditional Logic

Ternary Operator

```

{{ $json.status === 'active' ? 'Yes' : 'No' }}

{{ $json.count > 0 ? $json.items : [] }}

```

Nullish Coalescing

```

{{ $json.name ?? 'Unknown' }} // Use 'Unknown' if null/undefined

{{ $json.settings?.theme ?? 'light' }} // Safe navigation + default

```

Logical Operators

```

{{ $json.a && $json.b }} // Both truthy

{{ $json.a || $json.b }} // Either truthy

{{ !$json.deleted }} // Negation

```

Common Patterns

Safe Property Access

Avoid errors when properties might not exist:

```

{{ $json.user?.profile?.name ?? 'Guest' }}

```

Building URLs

```

{{ 'https://api.example.com/users/' + $json.userId }}

{{ \https://api.example.com/search?q=\${encodeURIComponent($json.query)}\ }}

```

Creating Objects

```

{{ { name: $json.firstName + ' ' + $json.lastName, email: $json.email } }}

```

Merging Objects

```

{{ { ...$json, status: 'processed' } }}

{{ Object.assign({}, $json.defaults, $json.overrides) }}

```

Extracting Unique Values

```

{{ [...new Set($json.items.map(i => i.category))] }}

```

Grouping Data

```

{{ $json.items.reduce((groups, item) => {

const key = item.category;

groups[key] = groups[key] || [];

groups[key].push(item);

return groups;

}, {}) }}

```

Expression Editor Tips

Use the Expression Editor

Click the gears icon next to any field. The expression editor shows:

  • Available variables
  • Autocomplete suggestions
  • Real-time preview of results

Test with Real Data

Run your workflow once with a manual trigger. Then edit nodes — the expression editor shows actual data from the last run.

Copy Paths from Input

In the input panel, hover over a field and click the copy icon. It gives you the exact expression path.

Debugging Expressions

Common Errors

"Cannot read property 'x' of undefined"

The object doesn't exist. Use optional chaining:

```

{{ $json.response?.data?.items }}

```

"x is not a function"

You're calling a method on the wrong type. Check what you're actually getting:

```

{{ typeof $json.value }}

```

Expression returns [object Object]

You're trying to use an object as a string. Stringify it:

```

{{ JSON.stringify($json.data) }}

```

Debug with Set Node

Add a Set node to inspect values:

  1. Add Set node after the problem area
  2. Create a field with your expression
  3. Run and inspect the output

Performance Considerations

Expressions run on every item. Heavy operations can slow things down:

Avoid in Expressions

  • Large array operations on every item
  • Multiple HTTP calls (use nodes instead)
  • Complex recursive functions

Better Patterns

  • Pre-process data in earlier nodes
  • Use Code node for complex transformations
  • Filter data before processing

Real-World Examples

Format Currency

```

{{ '$' + $json.amount.toFixed(2) }}

```

Extract Domain from Email

```

{{ $json.email.split('@')[1] }}

```

Calculate Age from Birthdate

```

{{ Math.floor($now.diff(DateTime.fromISO($json.birthdate), 'years').years) }}

```

Generate Slug from Title

```

{{ $json.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') }}

```

Mask Credit Card

```

{{ '** ** ' + $json.cardNumber.slice(-4) }}

```

Check Business Hours

```

{{ $now.hour >= 9 && $now.hour < 17 && $now.weekday <= 5 }}

```


Ready to master expressions? Nodox.ai challenges push you to transform data in ways that build real expression skills. Learn by solving problems, not memorizing syntax.

Start building today

Stop reading. Start building.

The best way to learn automation is by doing. Nodox.ai gives you hands-on challenges that build real skills — no passive tutorials, no hand-holding. Just problems to solve and skills that compound.