The Function node runs your own JavaScript code in a secure sandbox. Use it when transforms aren't enough and you need full programmatic control.
Writing function code
Open the Function node and write code in the built-in editor. Click Variables to insert data references at your cursor.
Default template
// Access workflow data
const inputs = {{inputs}};
const lastOutput = {{lastOutput}};
const variables = {{variables}};
const context = {{context}};
// Your custom logic here
const result = {
processed: true,
data: lastOutput,
};
// Return the result
return result;
Rules
- JavaScript only — Python and other languages are not supported in Function nodes.
- Must return a value — the returned object becomes the node's output for downstream steps.
- Read-only scope —
inputs,lastOutput, andvariablesare read-only; mutating them won't affect other nodes. - Size limit — code must be under 10 KB.
- No network or filesystem —
fetch,require,process, and file system access are blocked for security.
Examples
Calculate a total
const items = lastOutput.items || [];
const total = items.reduce((sum, item) => sum + (item.price || 0), 0);
return {
items,
total,
currency: variables.currency || 'USD',
};
Format data for an API
return {
recipient: inputs.email,
subject: `Order #${lastOutput.orderId} confirmed`,
body: `Hi ${lastOutput.customerName},\n\nYour order of $${lastOutput.amount} has been confirmed.`,
};
Parse and validate
const raw = lastOutput.content || '';
let parsed;
try {
parsed = JSON.parse(raw);
} catch {
return { error: 'Invalid JSON from AI node', raw };
}
if (!parsed.email) {
return { error: 'Missing email field', parsed };
}
return { valid: true, ...parsed };
Filter and transform a list
const records = lastOutput.data || [];
return {
active: records.filter(r => r.status === 'active'),
inactive: records.filter(r => r.status !== 'active'),
count: records.length,
};
Available scope
| Variable | Contents |
|---|---|
inputs | Trigger data (webhook body, manual inputs) |
lastOutput | Previous node's output |
variables | Workflow variables |
context | Execution metadata (ID, timestamps) |
Inside a Loop node, you also have access to loopItem and loopIndex.
Editor features
- Syntax highlighting and line numbers
- Expand to full-screen editor for longer scripts
- Variable inserter — click Variables to browse and insert
{{paths}} - Template placeholders like
{{inputs}}are replaced with actual values before your code runs
Error handling
If your code throws an error or has a syntax issue, the node fails and the error appears in the Execution Data tab. Common mistakes:
| Error | Fix |
|---|---|
SyntaxError | Check for missing brackets, semicolons, or typos |
undefined access | Guard with ?. or ` |
| Nothing returned | Ensure your code has a return statement |
| Code too large | Keep functions focused; split into multiple Function nodes |
Function vs Transform Code
Both support JavaScript, but they serve different purposes:
| Function Node | Transform → Code | |
|---|---|---|
| Purpose | General-purpose logic | Data transformation |
| Output | Any shape you return | Transformed input data |
| Editor | Full code editor with expand | Inline expression |
| Best for | Complex logic, validation, multi-step computation | Quick expressions on data shape |
Tips
- Start with the default template and modify incrementally.
- Test with a Manual trigger and check Execution Data after each change.
- Keep functions small and focused — chain multiple Function nodes for complex pipelines.
- Use Transform → Edit Fields for simple renaming; reserve Function for real logic.