Overview
In this lesson, you will learn how to harness the power of expressions in n8n to transform and manipulate data dynamically within your workflows. Expressions allow you to write single-line JavaScript code, use built-in functions, and query JSON data efficiently without needing extensive coding. By the end, you'll understand how to access data from previous nodes, apply built-in transformation functions, and format dates using Luxon, setting a strong foundation for more advanced automation with n8n.
For a deeper understanding of how data flows through n8n and how expressions interact with it, consider reviewing Understanding Data in n8n.
What Are Expressions in n8n?
Expressions in n8n provide a way to dynamically transform and access data inside nodes without writing long scripts. They allow you to:
- Access data from previous nodes or the current workflow execution.
- Use JavaScript single-line code to manipulate data.
- Leverage built-in data transformation functions provided by n8n.
- Query JSON data using JMESPath syntax.
- Format and manipulate dates using the Luxon library.
Expressions are different from the Code node, which allows multi-line JavaScript or Python code for advanced logic. Expressions are limited to single-line code snippets.
Where to Use Expressions in n8n
Expressions can be used in almost any node field that accepts dynamic input. You can toggle between fixed values and expressions using the Expression Editor in the node’s parameter fields.
How to Access Expressions
- Click on a field where you want to use an expression.
- Click the gear icon or the small dropdown next to the field.
- Select Expression.
- Type your code inside double curly braces
{{ ... }}. - The expression editor supports JavaScript syntax and shows suggestions for built-in functions.
Expressions are commonly used in nodes like the Set Node in n8n, where you can dynamically set or transform data fields using expressions.
Step-by-Step Example: Using Expressions to Transform Customer Data
Let's create a simple workflow to demonstrate expressions with some mock customer order data.
1. Create a New Workflow and Add a Manual Trigger
- Open your n8n workspace.
- Create a new workflow and rename it to
Expressions. - Add a Manual Trigger node to start the workflow manually.
2. Add a Set Node to Input Sample Data
- Add a Set node and rename it to
Customer Data. - Switch to the JSON mode.
- Paste the following JSON object representing an order:
{
"orderNumber": "12345",
"customerName": "John Doe",
"address": "123 Main St",
"email": "john.doe@genaiunplugged.io",
"order": {
"products": [
{ "name": "iPhone", "quantity": 1 },
{ "name": "AirPods", "quantity": 2 }
]
}
}
- Execute this node to confirm the data is loaded.
3. Add Another Set Node for Data Transformation
- Add another Set node and rename it to
Data Transformation. - In this node, you will extract and transform data using expressions.
Accessing Data Using Expressions
Access Properties Using Dot Notation
- Add a new field called
customerName(type: string). - Click Expression and type:
{{ $json.customerName }}
This accesses the customerName property from the previous node’s JSON data.
Access Properties Using Bracket Notation
- Add a field called
email(string). - Use the alternative bracket notation inside an expression:
{{ $json["email"] }}
Both dot and bracket notations work for accessing JSON properties.
Access Nested Array Elements
To access the name of the first product ordered:
{{ $json.order.products[0].name }}
Alternatively, you can use bracket notation for nested properties:
{{ $json["order"]["products"][0]["name"] }}
For more details on how data is structured and accessed in n8n, see Understanding Data in n8n.
Using Built-In Functions for Data Transformation
n8n provides many useful built-in functions accessible directly from the expression editor.
Example: Extracting the Domain from an Email
- Add a field
companyName(string). - Use an expression to extract the domain from the email:
{{ $json.email.extractDomain() }}
The extractDomain() function is a built-in n8n method that extracts the domain name from an email address.
Alternative Using JavaScript String Methods
You can achieve the same with JavaScript string functions:
{{ $json.email.split("@")[1] }}
This splits the email string at "@" and returns the domain part.
For a comprehensive list of built-in functions and how to use them, refer to the n8n Merge node documentation.
Conditional Expressions: Check for Empty Fields
Sometimes you want to check if a field exists or is empty and provide a default value.
Example: Check if Email Exists
- Add a field
isEmailFound(string). - Use the
ifEmptybuilt-in function:
{{ $ifEmpty($json.email, "email not found") }}
If the email field is empty or missing, this returns "email not found". Otherwise, it returns the email.
Testing the Condition
- Remove the email value in the
Customer Datanode and run the workflow. - The
isEmailFoundfield should now show"email not found".
Working with Dates and Times Using Luxon
n8n integrates the Luxon library for date and time manipulation.
Get Current Date and Format It
- Add a field
today(string). - Use the
$nowvariable with formatting:
{{ $now.format("yyyy-MM-dd") }}
This returns today’s date in the format YYYY-MM-DD.
Custom Date Format Examples
- Day-Month-Year format:
{{ $now.format("dd-MM-yyyy") }}
- Month-Day-Year format:
{{ $now.format("MM-dd-yyyy") }}
For more on date formatting and Luxon usage in n8n expressions, see the n8n Expressions Documentation.
Exploring More Built-In Functions
n8n has a rich library of built-in functions categorized by data type:
- Arrays: average, chunk, compact, difference, etc.
- Booleans: toInt (false → 0, true → 1).
- Numbers: ceiling, floor, formatting, isEven, isOdd, etc.
- Objects: isEmpty, merge, hasField.
- Strings: extractDomain, extractEmail, extractURL, createHash, etc.
- DateTime: format, plus, minus, diff, etc.
You can find the full list in the official n8n docs under Built-In Functions and Variables.
Limitations of Expressions and When to Use the Code Node
- Expressions are limited to single-line JavaScript code.
- You cannot write multi-line functions, loops, or complex logic inside expressions.
- Attempting multi-line code or function declarations inside expressions results in syntax errors.
Example: Calculating Days Elapsed Since Start of Year
You can calculate the difference between dates using built-in Luxon methods inside an expression:
{{ $now.diff(DateTime.fromISO("2025-01-01"), "days").toObject().days.toFixed(2) }}
This returns the number of days elapsed since January 1, 2025.
Why Multi-Line Code Doesn't Work in Expressions
Trying to define a function inside an expression, such as:
{{
function example() {
// multi-line code
}
example();
}}
will throw an error because expressions do not support multi-line code blocks.
Use the Code Node for Complex Logic
For multi-line scripts, complex calculations, or loops, use the Code node, which supports full JavaScript or Python code execution. Learn more about this in the Code Node in n8n lesson.
Troubleshooting & Common Mistakes
- Forgetting double curly braces: Expressions must be wrapped in
{{ ... }}to be interpreted as code. - Using multi-line code in expressions: Only single-line expressions are supported; use the Code node for complex logic.
- Incorrect property access: Use
$json.propertyor$json["property"]correctly depending on the property name syntax. - Not selecting "Expression" mode: Ensure you switch the field input from fixed value to expression mode.
- Date formatting errors: Use correct Luxon format strings (e.g.,
yyyy-MM-dd), or the output may be unexpected. - Referencing nodes by name: Use
$node["NodeName"].json["property"]to access data from other nodes beyond the immediate previous node.
Quick Reference: Common Expression Patterns in n8n
| Use Case | Expression Example | Notes |
|---|---|---|
| Access property | {{ $json.customerName }} |
Dot notation for direct access |
| Access nested array element | {{ $json.order.products[0].name }} |
Access first product name |
| Extract domain from email | {{ $json.email.extractDomain() }} |
Built-in function |
| Split string by character | {{ $json.email.split("@")[1] }} |
JavaScript string method |
| Conditional default value | {{ $ifEmpty($json.email, "email not found") }} |
Provides fallback if empty |
| Current date formatted | {{ $now.format("yyyy-MM-dd") }} |
Luxon date formatting |
| Date difference in days | {{ $now.diff(DateTime.fromISO("2025-01-01"), "days").days }} |
Calculate days elapsed |
| Access data from another node | {{ $node["Customer Data"].json["email"] }} |
Access data from named node |
Additional Resources
By mastering expressions, you unlock powerful data manipulation capabilities in n8n with minimal coding. This skill bridges the gap between no-code and low-code automation, enabling you to build more flexible and dynamic workflows. In the next lessons, you will explore writing custom multi-line code using the Code node and making API calls with the HTTP node.