Pipedream $.flow.exit, $.respond and other $ helpers in n8n
Updated 2026-10-21 · 5 min read
Pipedream code steps control the workflow through the $ object: $.flow.exit() stops it, $.respond() answers the HTTP caller, $.export() shares data, $.flow.delay() pauses it. n8n has no $ object for this. The same control lives in nodes and in what a Code node returns. This page maps each helper to its n8n equivalent, shows before-and-after code, and points out the cases that need a workflow change rather than a code change.
Quick mapping
| Pipedream | n8n |
|---|---|
return $.flow.exit("reason") |
return [] in the Code node, or an If / Filter node |
$.respond({ status, headers, body }) |
Respond to Webhook node (Webhook set to "Using 'Respond to Webhook' Node") |
$.respond({ immediate: true, ... }) |
Respond to Webhook placed early |
$.export("name", value) |
A field on the returned item |
return value ($return_value) |
return [{ json: value }] |
$.flow.delay(ms) |
Wait node between nodes |
$.flow.suspend() + resume_url |
Wait node "On Webhook Call" + $execution.resumeUrl |
$.flow.rerun(delay, ctx, max) |
Retry On Fail, or Wait + If + loop |
$.flow.trigger() (alpha) |
Execute Sub-workflow node |
$.send.http(...) |
HTTP Request node |
$.service.db |
Data Table node or workflow static data |
Pipedream documents these on its Node.js and triggers pages.
$.flow.exit
In Pipedream, return $.flow.exit("no email") ends the execution immediately; later steps don't run.
// Pipedream
export default defineComponent({
async run({ steps, $ }) {
const body = steps.trigger.event.body;
if (!body.email) return $.flow.exit("no email");
return { email: body.email };
},
});
In n8n, a Code node that returns no items ends that branch: the nodes after it receive nothing and don't run.
// n8n Code node, Run Once for All Items
const body = $('Webhook').first().json.body;
if (!body.email) return [];
return [{ json: { email: body.email } }];
Two differences:
- The execution succeeds in n8n; it just has no more work. If you want the stop to show as a failure (and alert someone), use a Stop and Error node instead.
- The exit reason isn't recorded anywhere. If you relied on it in Pipedream's event history, return an item with the reason to a logging node instead of an empty array.
When the condition is simple, put an If or Filter node in front of the step and drop the exit from the code entirely. It's visible on the canvas, which return [] isn't.
$.respond
Pipedream's $.respond({ status, headers, body }) answers the HTTP request that triggered the workflow. Without immediate: true, the response goes out when the workflow ends; with it, right away. Without any $.respond, Pipedream returns 200 with a "Success!" page.
n8n separates this into two settings:
- Webhook node > Respond: set to Using 'Respond to Webhook' Node.
- Respond to Webhook node where the answer should go, with Respond With JSON, Response Code and Response Headers options.
// Pipedream
await $.respond({
status: 201,
headers: { "X-Request-Id": steps.trigger.event.headers["x-request-id"] },
body: { id: steps.create.$return_value.id },
});
n8n: Respond to Webhook node after the "create" node, Respond With JSON, Response Code 201, Response Headers X-Request-Id = {{ $('Webhook').first().json.headers['x-request-id'] }}, Response Body:
{{ { "id": $('create').first().json.id } }}
Immediate vs at the end
| Pipedream | n8n placement |
|---|---|
$.respond({...}) (default) |
Respond to Webhook as the last node |
$.respond({ immediate: true, ... }) |
Respond to Webhook early, processing continues after it |
The n8n docs let you place the node anywhere; in our tests the response goes out when the node runs and the nodes after it keep going. If the workflow fails before reaching the node, the caller gets a 500 (Respond to Webhook docs). Only the first Respond to Webhook node that runs counts.
$.respond then $.flow.exit
A common Pipedream pattern: validate, respond with an error, exit.
if (!body.email) {
await $.respond({ status: 400, body: { error: "email required" } });
return $.flow.exit("invalid");
}
In n8n: If node on email is not empty; the false branch goes to a Respond to Webhook with code 400 and ends; the true branch continues and responds 200 at the end.
$.export and return values
// Pipedream
$.export("domain", email.split("@")[1]);
return { email };
// later: steps.parse.domain, steps.parse.$return_value.email
// n8n
return [{ json: { email, domain: email.split('@')[1] } }];
// later: $('parse').first().json.domain, $('parse').first().json.email
Keep the node name equal to the Pipedream step name and the references translate mechanically.
$.flow.delay and $.flow.suspend
$.flow.delay(ms) paused the workflow at the end of the step (1 ms to one year) and returned cancel_url and resume_url (delay docs). $.flow.suspend() waited until resume_url was called (cancelled after 24 hours by default). Neither can happen inside an n8n Code node: split the step in two and put a Wait node between them, with Resume set to After Time Interval (delay) or On Webhook Call (suspend). The Wait node offloads executions for waits of 65 seconds or more.
$.flow.rerun
$.flow.rerun(delay, context, maxRetries) reran a step, typically to poll a job or retry an API call (rerun docs). There's no single n8n equivalent:
| Pipedream use | n8n |
|---|---|
| Retry on a transient error | Node Settings: Retry On Fail, Max Tries, Wait Between Tries |
| Poll until a job finishes | HTTP Request → If (done?) → Wait → back to HTTP Request, with a counter to stop |
| Wait for a callback | Wait node, On Webhook Call |
What our converter does with $
Our converter keeps your code and wraps it in a Code node that provides a $ object:
$.exportand return values become fields on the output item, and step names are kept as node names, sosteps.x.yreferences resolve.$.flow.exitworks: the wrapped step returns no items.$.respondis captured, and a Respond to Webhook node is inserted after the step, with the Webhook node set to respond through it. Status and body are carried over; set custom headers on the Respond to Webhook node by hand. If the step exits right after responding, the response is still sent.$.flow.delayand$.flow.rerunare reported as manual work; the wrapped step throws a clear error if it reaches them.$.flow.triggerisn't converted or reported yet: a wrapped step that calls it fails at runtime. Search your code for it and rebuild those calls as Execute Sub-workflow nodes.
See what a step uses with the free code step checker, or run the whole export through the converter. The report and 1 workflow are free. Full export: $3 per workflow, $19 minimum — coming soon. The rest of the code-step mapping is in Pipedream code steps to n8n.
Not affiliated with Pipedream or n8n.
FAQ
- What is the n8n equivalent of $.flow.exit()?
- Return an empty array from the Code node, so the following nodes get no items and don't run. For a condition that's easy to express, an If or Filter node before the step does the same without code.
- How do I replace $.respond() in n8n?
- Set the Webhook node's Respond option to Using 'Respond to Webhook' Node and add a Respond to Webhook node where the response should be sent. Status, headers and body are set in that node.
- How do I respond immediately like $.respond({ immediate: true })?
- Place the Respond to Webhook node early in the workflow. The caller gets the response when it runs; in our tests the nodes after it keep running.
- Is there an n8n equivalent of $.flow.rerun()?
- Not a direct one. Use Retry On Fail on the node for retries, or a Wait node plus an If node looping back for polling.
- What replaces $.export() in n8n?
- Return the value as a field of the output item. Later nodes read it with $('Step name').first().json.field.
Related
Sources
- https://pipedream.com/docs/workflows/building-workflows/code/nodejs
- https://pipedream.com/docs/workflows/building-workflows/triggers
- https://pipedream.com/docs/workflows/building-workflows/code/nodejs/delay
- https://pipedream.com/docs/workflows/building-workflows/code/nodejs/rerun
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait
- https://docs.n8n.io/build/understand-workflows/workflow-components/work-with-nodes