In this chapter, we'll unlock one of n8n's most powerful features: expressions. Expressions allow you to dynamically access, transform, and manipulate data as it flows through workflows, turning static automations into intelligent, adaptive systems.
Expression: Code wrapped in double curly braces {{ }} that dynamically evaluates to produce a value. Expressions can access data, perform calculations, manipulate strings, and apply JavaScript functions.
All expressions must be wrapped in {{ }}. Without these braces, n8n treats content as literal text.
Hello, $json.name → Outputs exactly as writtenHello, {{ $json.name }} → Outputs "Hello, John Smith"| Expression | What It Accesses |
|---|---|
| {{ $json }} | Entire JSON object |
| {{ $json.propertyName }} | Specific property |
| {{ $json.nested.property }} | Nested property |
| {{ $json.array[0] }} | First array item |
| {{ $node["Node Name"].json }} | Data from specific node |
| Method | Purpose | Example |
|---|---|---|
| .toUpperCase() | Convert to uppercase | {{ $json.name.toUpperCase() }} |
| .toLowerCase() | Convert to lowercase | {{ $json.email.toLowerCase() }} |
| .trim() | Remove whitespace | {{ $json.name.trim() }} |
| .replace() | Replace text | {{ $json.phone.replace("-", "") }} |
| .split() | Split into array | {{ $json.tags.split(",") }} |
{{ $json.name.toLowerCase().replace(" ", ".") + "@company.com" }}{{ $json.fullName.split(" ")[0] }}{{ $json.description.slice(0, 100) + "..." }}| Operation | Example | Result |
|---|---|---|
| Addition | {{ $json.price + 5 }} | 105 (if price = 100) |
| Multiplication | {{ $json.quantity * $json.price }} | 500 (if qty=5, price=100) |
| Percentage | {{ $json.total * 0.08 }} | 8 (8% of 100) |
{{ ($json.subtotal * 0.08).toFixed(2) }}{{ Math.round((1 - $json.salePrice / $json.originalPrice) * 100) }}%{{ ($json.values.reduce((a, b) => a + b, 0) / $json.values.length).toFixed(2) }}| Expression | Output |
|---|---|
| {{ $now.toFormat('yyyy-MM-dd') }} | 2025-11-21 |
| {{ $now.toFormat('MMM dd, yyyy') }} | Nov 21, 2025 |
| {{ $now.toFormat('HH:mm:ss') }} | 14:30:00 |
{{ $now.plus({ days: 7 }).toFormat('yyyy-MM-dd') }}{{ $now.minus({ days: 30 }).toFormat('yyyy-MM-dd') }}{{ $now.startOf('month').toFormat('yyyy-MM-dd') }}{{ $now.diff($json.startDate, 'days').days }}Syntax: {{ condition ? valueIfTrue : valueIfFalse }}
{{ $json.total > 1000 ? "VIP" : "Standard" }}{{ $now.hour < 12 ? "Good morning" : "Good afternoon" }}{{ $json.score >= 90 ? "A" : $json.score >= 80 ? "B" : "C" }}| Method | Purpose |
|---|---|
| .length | Number of items |
| .map() | Transform each item |
| .filter() | Keep items matching condition |
| .join() | Combine into string |
{{ $json.products.map(p => p.name).join(", ") }}{{ $json.items.reduce((sum, item) => sum + item.price, 0) }}{{ $json.products.filter(p => p.price > 100) }}{{ ($json.subtotal + ($json.subtotal < 50 ? 5.99 : 0)).toFixed(2) }}
Free shipping over $50, otherwise $5.99
{{ $json.lifetimeValue > 10000 ? "Platinum" : $json.lifetimeValue > 5000 ? "Gold" : "Silver" }}
$json.user?.profile?.name{{ $json.quantity || 1 }}Solution: Use optional chaining or check existence first
Solution: Access specific properties or use JSON.stringify()
Create personalized greeting based on time and customer name
Calculate final price with discounts and tax
In Chapter 5, we'll explore workflow control and logic. You'll learn IF nodes, Switch nodes, loops, error handling, and building workflows that make intelligent decisions.
n8n Textbook | Chapter 4: Expressions and Data Manipulation
© 2025 IOLEBA | Dr. Marcus Lee
Originally Published: November 2025