Learn how to use expressions in n8n to dynamically access, manipulate, and transform data in workflows with step-by-step examples and best practices.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Expressions in n8n are a powerful way to dynamically access, manipulate, and transform data within your workflows. They allow you to reference data from previous nodes, perform calculations, manipulate strings, and create conditional logic. You can use expressions in most fields across n8n nodes by wrapping your code in double curly braces like {{ $your_expression }}
.
Understanding n8n Expressions
Expressions in n8n provide a way to work with data dynamically in your workflows. They enable you to:
Step 1: Accessing the Expression Editor
To use expressions in n8n, you need to know how to access the expression editor:
{ }
) on the right side of the field.Alternatively, you can type {{
directly in the field to start an expression.
Step 2: Understanding the Basics of Expressions
All expressions in n8n are wrapped in double curly braces: {{ }}
Inside these braces, you can write JavaScript code, use n8n variables, or utilize built-in methods.
For example:
{{ 2 + 2 }}
This simple expression will output 4
.
Step 3: Accessing Data from Previous Nodes
One of the most common uses of expressions is to access data from previous nodes:
To access data from the first output item of the previous node:
{{ $node["Previous Node Name"].json.fieldName }}
To access data from a specific item in a previous node's output:
{{ $node["Previous Node Name"].json["fieldName"] }}
To access data from a specific index in an array:
{{ $node["Previous Node Name"].json.arrayField[0] }}
Step 4: Using the Current Node Data
You can also reference data within the current execution:
To access the current item being processed:
{{ $json.fieldName }}
To access all items in the current execution:
{{ $items }}
To access a specific index from all items:
{{ $items[0].json.fieldName }}
Step 5: Working with Variables and Parameters
n8n provides several special variables you can use in expressions:
Workflow variables:
{{ $workflow.id }}
{{ $workflow.name }}
{{ $workflow.active }}
Execution variables:
{{ $execution.id }}
{{ $execution.mode }}
{{ $execution.resumeUrl }}
Environment variables:
{{ $env.MY\_VARIABLE }}
Step 6: String Manipulation
You can perform various string operations in expressions:
Concatenation:
{{ "Hello, " + $json.name + "!" }}
Template literals (for more readable code):
{{ `Hello, ${$json.name}!` }}
String methods:
{{ $json.email.toLowerCase() }}
{{ $json.name.toUpperCase() }}
{{ $json.text.trim() }}
{{ $json.message.slice(0, 10) }}
Step 7: Working with Numbers and Math
Perform mathematical operations within expressions:
Basic arithmetic:
{{ $json.price \* $json.quantity }}
{{ $json.total / $json.count }}
{{ $json.value + 10 }}
{{ $json.number - 5 }}
Using Math functions:
{{ Math.round($json.price) }}
{{ Math.floor($json.value) }}
{{ Math.ceil($json.number) }}
{{ Math.max($json.a, $json.b, $json.c) }}
Formatting numbers:
{{ $json.price.toFixed(2) }}
Step 8: Date and Time Operations
Work with dates in your expressions:
Getting the current date and time:
{{ new Date().toISOString() }}
{{ Date.now() }}
Formatting dates:
{{ new Date($json.timestamp).toLocaleDateString() }}
{{ new Date($json.created\_at).toLocaleTimeString() }}
Date calculations:
// Add 7 days to a date
{{ new Date(new Date($json.date).getTime() + (7 _ 24 _ 60 _ 60 _ 1000)).toISOString() }}
Step 9: Conditional Logic
Implement decision-making in your expressions:
Ternary operator for simple conditions:
{{ $json.age >= 18 ? "Adult" : "Minor" }}
More complex conditions:
{{
$json.status === "active" ?
"Account is active" :
($json.status === "pending" ?
"Account is pending approval" :
"Account is inactive")
}}
Logical operators:
{{ $json.isSubscribed && $json.hasConfirmedEmail ? "Fully registered" : "Incomplete registration" }}
Step 10: Array Operations
Manipulate arrays in your expressions:
Map through an array:
{{
$json.items.map(item => {
return {
id: item.id,
name: item.name.toUpperCase()
};
})
}}
Filter an array:
{{
$json.products.filter(product => product.price > 100)
}}
Find in an array:
{{
$json.users.find(user => user.id === $json.searchId)
}}
Reduce an array:
{{
$json.orderItems.reduce((total, item) => total + (item.price \* item.quantity), 0)
}}
Step 11: Object Manipulation
Work with objects in your expressions:
Creating new objects:
{{
{
fullName: $json.firstName + " " + $json.lastName,
email: $json.email.toLowerCase(),
isActive: $json.status === "active"
}
}}
Merging objects:
{{
{...$json, updated: true, timestamp: Date.now()}
}}
Extracting specific properties:
{{
(({name, email, id}) => ({name, email, id}))($json)
}}
Step 12: Using Regular Expressions
Leverage regular expressions for pattern matching:
Testing if a string matches a pattern:
{{ /^[A-Za-z0-9.\_%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}$/.test($json.email) }}
Extracting parts of a string:
{{
$json.url.match(/https://([^/]+)/)[1]
}}
Replacing text:
{{
$json.text.replace(/sensitive/gi, "[REDACTED]")
}}
Step 13: Using JSON Methods
Work with JSON data in your expressions:
Parse JSON from a string:
{{
JSON.parse($json.jsonString)
}}
Convert to JSON string:
{{
JSON.stringify($json.data)
}}
Pretty print JSON:
{{
JSON.stringify($json, null, 2)
}}
Step 14: Error Handling in Expressions
Handle potential errors in your expressions:
Using the nullish coalescing operator:
{{
$json.user?.name ?? "Unknown User"
}}
Using try-catch:
{{
(function() {
try {
return JSON.parse($json.possiblyInvalidJson);
} catch (error) {
return { error: "Invalid JSON" };
}
})()
}}
Checking if properties exist:
{{
$json.hasOwnProperty('email') ? $json.email : 'No email provided'
}}
Step 15: Working with n8n Built-in Methods
n8n provides several built-in utility methods:
$itemIndex - the index of the current item:
{{
"Processing item #" + $itemIndex
}}
$if - for conditional logic:
{{
$if($json.status === "active",
"User is active",
"User is not active")
}}
$jmespath - for querying JSON:
{{
$jmespath($json, "users[?age > `30`].name")
}}
Step 16: Complex Expression Examples
Here are some more advanced examples of what you can do with expressions:
Generate a UUID:
{{
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() \* 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
})
}}
Format a phone number:
{{
$json.phoneNumber.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3')
}}
Calculate time difference in hours:
{{
Math.round((new Date() - new Date($json.timestamp)) / (1000 _ 60 _ 60))
}}
Step 17: Using Expressions with HTTP Requests
When working with HTTP Request nodes, expressions are particularly useful:
Dynamic URL construction:
{{
`https://api.example.com/users/${$json.userId}/profile`
}}
Building query parameters:
{{
`https://api.example.com/search?q=${encodeURIComponent($json.searchTerm)}&limit=${$json.limit}`
}}
Constructing headers:
{{
{
"Authorization": `Bearer ${$node["Auth Node"].json.accessToken}`,
"Content-Type": "application/json",
"X-Custom-Header": $json.customValue
}
}}
Step 18: Using Expressions with If Node
The If Node relies heavily on expressions for its conditions:
Simple comparison:
{{
$json.status === "approved"
}}
Multiple conditions:
{{
$json.age >= 18 && $json.hasConsent === true
}}
Complex logic:
{{
($json.userType === "premium" || $json.subscriptionMonths > 6) && $json.accountActive === true
}}
Step 19: Using Expressions with Function Nodes
In Function nodes, you don't need to use the double curly braces syntax, but you can reference the same variables and data:
// Example Function Node code
const items = [];
// Process each input item
for (let i = 0; i < $input.all().length; i++) {
const item = $input.all()[i];
// Transform the data
const newItem = {
id: item.json.id,
name: item.json.name.toUpperCase(),
email: item.json.email.toLowerCase(),
processedAt: new Date().toISOString()
};
items.push({json: newItem});
}
return items;
Step 20: Debugging Expressions
When your expressions don't work as expected, try these debugging techniques:
// In a Function node
console.log('Data to debug:', $input.item);
return $input.item;
Step 21: Best Practices for Using Expressions
Follow these guidelines to use expressions effectively:
Step 22: Common Expression Pitfalls and Solutions
Avoid these common mistakes:
{{ $json.user-name }}
{{ $json["user-name"] }}
{{ $json.user.email }}
(crashes if user is null){{ $json.user?.email ?? "No email" }}
$json.Name
is different from $json.name
{{ $json.price + $json.tax }}
(concatenates if they're strings){{ Number($json.price) + Number($json.tax) }}
Step 23: Using Expressions with Loops
When working with arrays and loops:
Map transformation:
{{
$json.items.map(item => {
return {
id: item.id,
formattedPrice: `$${item.price.toFixed(2)}`,
inStock: item.quantity > 0
};
})
}}
Finding specific items:
{{
$json.products.filter(product =>
product.category === 'electronics' &&
product.price < 1000
)
}}
Calculating totals:
{{
$json.orderItems.reduce((sum, item) => sum + (item.price \* item.quantity), 0).toFixed(2)
}}
Conclusion
Expressions in n8n are extremely powerful and flexible, allowing you to create dynamic workflows that can adapt to different data and conditions. By mastering expressions, you'll be able to create more sophisticated automation without needing to rely as heavily on Function nodes or external code. Start with simple expressions and gradually build up to more complex ones as you become more comfortable with the syntax and capabilities.
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.