Expression Runtime
Relevant source files
The following files were used as context for generating this wiki page:
- packages/@n8n/ai-workflow-builder.ee/src/code-builder/prompts/index.ts
- packages/@n8n/workflow-sdk/src/prompts/sdk-reference/sdk-language.ts
- packages/quality/testing/playwright/tests/e2e/workflows/editor/expressions/modal.spec.ts
- packages/@n8n/workflow-sdk/src/codegen/codegen.test.ts
- packages/@n8n/workflow-sdk/src/prompts/best-practices/guides/data-analysis.ts
The Expression Runtime enables dynamic data evaluation within n8n workflows using {{ ... }} syntax. It processes JavaScript at runtime to resolve values from incoming data, environment variables, or execution context. This runtime operates independently of the static workflow graph definition.
Sources: packages/@n8n/workflow-sdk/src/prompts/sdk-reference/sdk-language.ts:156-160, packages/quality/testing/playwright/tests/e2e/workflows/editor/expressions/modal.spec.ts:1-10
Expression Architecture
Expressions differ from the Workflow SDK builder code. While builder code uses a restricted subset of TypeScript to define the workflow structure, expressions run full JavaScript during execution. This allows the use of native methods like .map(), .filter(), and .join() that are otherwise blocked in the builder SDK.
Sources: packages/@n8n/workflow-sdk/src/prompts/sdk-reference/sdk-language.ts:156-170
Evaluation Flow
The runtime takes a string containing expression syntax and resolves it against the current node's execution context.
The diagram shows how the runtime distinguishes between literal text and dynamic code segments to produce a final value.
Sources: packages/quality/testing/playwright/tests/e2e/workflows/editor/expressions/modal.spec.ts:45-102
Context Variables
The runtime exposes specific global objects and variables to the expression context. These allow users to reference data from the current node or previous steps in the workflow.
| Variable | Description |
|---|---|
$json | Accesses the JSON data of the current item. |
$input | Provides access to the full input object including items and metadata. |
$(nodeName) | References output data from a specific named node. |
$now | Returns a Luxon object representing the current date and time. |
$parameter | Accesses parameters configured in the current node. |
Sources: packages/quality/testing/playwright/tests/e2e/workflows/editor/expressions/modal.spec.ts:85-102, packages/@n8n/ai-workflow-builder.ee/src/code-builder/prompts/index.ts:588-590
Resolvable Data Types
The Expression Runtime supports resolving various JavaScript data types. This functionality is validated through the Expression Editor Modal.
Primitive Resolvables
The runtime evaluates basic arithmetic, string concatenation, and boolean logic.
- Numbers:
{{ 1 + 2 }}resolves to3. - Strings:
{{ "ab" + "cd" }}resolves toabcd. - Booleans:
{{ true && false }}resolves tofalse.
Complex Structures
- Objects: Resolves JSON-like objects and supports property access (e.g.,
{{ { a : 1 }.a }}). - Arrays: Supports array creation and index-based access (e.g.,
{{ [1, 2, 3][0] }}).
Sources: packages/quality/testing/playwright/tests/e2e/workflows/editor/expressions/modal.spec.ts:45-80
Expression Codegen and SDK Integration
In the n8n Workflow SDK, expressions must be wrapped in the expr() helper. This tells the generator to treat the string as an expression rather than a literal value.
Syntax Rules
- Always use single or double quotes within
expr(). - Do not use backtick template literals for the outer wrapper.
- Use string concatenation for multiline expressions.
- Variables like
$jsonand$nowmust reside inside the{{ }}brackets.
Sources: packages/@n8n/ai-workflow-builder.ee/src/code-builder/prompts/index.ts:584-594
Example Implementations
The following table illustrates correct vs. incorrect SDK expression usage:
| Pattern | SDK Code Example |
|---|---|
| Correct | expr('Hello {{ $json.name }}') |
| Correct | expr('Daily Digest - {{ $now.toFormat("MMMM d") }}') |
| Incorrect | expr('Hello ' + $json.name) |
| Incorrect | expr('{{ ' + JSON.stringify(...) + ' }}') |
Sources: packages/@n8n/ai-workflow-builder.ee/src/code-builder/prompts/index.ts:587-594, packages/@n8n/workflow-sdk/src/codegen/codegen.test.ts:155-165
Usage Best Practices
Expressions are primarily used in Edit Fields (Set) nodes for data transformation and shaping.
- Data Cleaning: Use expressions to rename fields, convert data types (e.g., using
Number()orparseInt()), or add calculated fields. - Filtering: Reference expression results in Filter or IF nodes to route workflow execution based on dynamic conditions.
- Handling Convergence: When a node receives data from multiple branches, use optional chaining in expressions (e.g.,
{{ $json.data?.approved ?? $json.status }}) to handle potential missing fields.
Sources: packages/@n8n/workflow-sdk/src/prompts/best-practices/guides/data-analysis.ts:55-80, packages/@n8n/ai-workflow-builder.ee/src/code-builder/prompts/index.ts:536-538
Summary
The Expression Runtime provides a flexible environment for runtime data manipulation. It separates workflow structure from dynamic logic by allowing users to embed full JavaScript capabilities within nodes using the standard {{ }} delimiters. While the Builder SDK restricts JavaScript to maintain graph integrity, the runtime ensures that data processing remains expressive and powerful.