Function Node

Write custom JavaScript to process data, calculate values, and return results.

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

  1. JavaScript only — Python and other languages are not supported in Function nodes.
  2. Must return a value — the returned object becomes the node's output for downstream steps.
  3. Read-only scopeinputs, lastOutput, and variables are read-only; mutating them won't affect other nodes.
  4. Size limit — code must be under 10 KB.
  5. No network or filesystemfetch, 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

VariableContents
inputsTrigger data (webhook body, manual inputs)
lastOutputPrevious node's output
variablesWorkflow variables
contextExecution 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:

ErrorFix
SyntaxErrorCheck for missing brackets, semicolons, or typos
undefined accessGuard with ?. or `
Nothing returnedEnsure your code has a return statement
Code too largeKeep functions focused; split into multiple Function nodes

Function vs Transform Code

Both support JavaScript, but they serve different purposes:

Function NodeTransform → Code
PurposeGeneral-purpose logicData transformation
OutputAny shape you returnTransformed input data
EditorFull code editor with expandInline expression
Best forComplex logic, validation, multi-step computationQuick 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.