Pipedream Workflows and String stop running on March 31, 2027. All Workflows data, including connected accounts and their OAuth tokens, is deleted by April 30, 2027. Pipedream Connect is not affected.
Neither Pipedream nor n8n offers an importer, so moving to n8n means rebuilding each workflow in n8n's own format. Most of it is mechanical once you know the equivalents. This post covers the equivalents, the parts that break, and an order of work.
1. Get your workflows out
You have three ways to get workflow definitions:
-
The official export. In a project, open Settings and click Export Workflows. Pipedream writes a ZIP to the project's File Store: a
manifest.jsonplus one JSON file per workflow, with triggers, steps, code, props and branches. Pipedream's docs say File Stores are an Advanced-plan feature, so on Free or Basic the button may not work. -
GitHub Sync. If a project was ever synced, the repository has a
workflow.yamlper workflow and a file per code step. -
The REST API.
GET https://api.pipedream.com/v1/workflows/{id}?org_id=o_xxxwith an API key returns a workflow's definition. It isn't confirmed on Free or Basic plans, so try one workflow first.
Whatever you use, some things never come out:
- secret values, which are exported as
<redacted>; - OAuth tokens, which become just an account ID;
- environment variable values;
- data store records and File Store files;
- event history;
- the code of private components.
Read manifest.json first: its warnings list names every redacted prop. One export holds at most 500 workflows or 256 MB.
Save a few real sample events from each workflow now. On Free and Basic, Pipedream keeps only the last 100 events or 7 days. You'll want them to test the n8n version.
2. Choose n8n Cloud or self-hosted
This choice depends mostly on your code steps:
-
n8n Cloud. The Code node can load only
cryptoandmomentin JavaScript. Python steps can't import anything at all. -
Self-hosted n8n. Set
NODE_FUNCTION_ALLOW_EXTERNAL=axios,lodash(andNODE_FUNCTION_ALLOW_BUILTINfor Node's own modules), and install the packages where the task runner can load them.
If most of your imports are HTTP clients and date libraries, Cloud is fine: HTTP calls can use this.helpers.httpRequest() inside the Code node, and Luxon is built in. If you depend on SDKs or Python libraries, self-hosting saves a lot of rewriting.
3. Map the triggers
| Pipedream | n8n |
|---|---|
| HTTP / webhook trigger | Webhook node |
$.respond() in a step |
Respond to Webhook node, with the Webhook node's Respond option set to "Using 'Respond to Webhook' Node" |
| Schedule (cron or interval) | Schedule Trigger |
| App event (new row, new email…) | The app's n8n trigger node, if it exists |
Three things bite here:
-
Webhook URLs change. Every service that calls your
*.m.pipedream.netURL needs the new n8n production URL. -
Some intervals don't fit one rule. n8n's interval rules count seconds up to 59, minutes up to 59, hours up to 23 and days up to 31. "Every 90 minutes" becomes two cron rules:
0 0,3,6,9,12,15,18,21 * * *and30 1,4,7,10,13,16,19,22 * * *. -
Polling triggers batch items. Pipedream ran your workflow once per new row or email. n8n's polling triggers (Google Sheets, Gmail, Airtable…) return every new item in one execution. Code written for a single event quietly processes only the first one. Either put Loop Over Items after the trigger and call the rest of the flow with Execute Workflow per item, or rewrite the code for
$input.all().
4. Map steps and branches
| Pipedream | n8n |
|---|---|
| Registry action (Slack, Google Sheets…) | The app's n8n node, or HTTP Request |
| If/else block | If node (one condition branch) or Switch node (several) |
| Switch block | Switch node in Rules mode |
Filter step, $.flow.exit()
|
If node with nothing connected to the branch that stops |
| Delay | Wait node |
| Parallel block | Branches from one node, then a Merge node |
| Loop block | Loop Over Items |
One difference changes results silently: Pipedream's rule builder compares text without regard to case, and n8n's If node is case-sensitive unless you turn on its Ignore Case option.
Steps after a Pipedream block read steps.<block>.$return_value, the result of whichever branch ran. In n8n, add a node where the branches meet and point later expressions at it.
Prop expressions change syntax too: {{steps.trigger.event.body.email}} becomes {{ $('trigger').first().json.body.email }}. Name your n8n nodes after the old step names and most references translate one to one.
5. Convert the code steps
A Pipedream Node.js step:
import axios from "axios";
export default defineComponent({
async run({ steps, $ }) {
const email = steps.trigger.event.body.email;
const { data } = await axios.get("https://api.example.com/users", { params: { email } });
if (!data.active) return $.flow.exit("inactive user");
$.export("userId", data.id);
return data;
},
});
The same logic in an n8n Code node ("Run Once for All Items", with the Webhook node named trigger):
const email = $('trigger').first().json.body.email;
const data = await this.helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/users',
qs: { email },
json: true,
});
// Like $.flow.exit(): no items out, so nothing after this node runs.
if (!data.active) return [];
return [{ json: { ...data, userId: data.id } }];
The rules behind it:
-
steps.x.$return_valuebecomes$('x').first().json. -
$.export()and the return value become fields of the items you return. n8n items are always objects, so wrap a string or an array. -
$.flow.exit()becomesreturn []. - axios, got and node-fetch become
this.helpers.httpRequest(), which works on n8n Cloud. - Pipedream data stores become workflow static data (
$getWorkflowStaticData('global')) or n8n Data tables. Static data is only saved for published workflows started by a trigger, not for manual test runs. - Code nodes can't read n8n credentials by design. If a step used
this.someApp.$auth, move that API call into an HTTP Request node that uses an n8n credential.
6. Credentials, secrets and variables
- Create an n8n credential for every connected account and select it on the matching nodes.
- Re-enter redacted secrets in credentials, or as n8n Variables. Variables are available on n8n Cloud Pro and Enterprise and on self-hosted Business and Enterprise.
- Since n8n 2.0,
N8N_BLOCK_ENV_ACCESS_IN_NODEdefaults totrue, so Code nodes can't read environment variables unless you change it on a self-hosted instance.
7. Import, test and cut over
- Import each workflow JSON from the editor (workflow menu, Import from File), or in bulk with the public API:
POST /api/v1/workflowswith anX-N8N-API-KEYheader. The API isn't available on the Cloud free trial. - Imported workflows start unpublished. In n8n 2.x you publish a workflow instead of toggling it active.
- Replay your saved sample events and compare the outputs with Pipedream's.
- Point each webhook sender at the new production URL. Watch the Executions list for a few days, then turn the Pipedream workflow off.
- Copy data store records and File Store files out before April 30, 2027.
Start with the workflows that have the most outside dependencies (webhook senders, OAuth apps), because those take the longest to switch. If you're stuck on a specific Pipedream pattern, ask in the comments.
This article was written with the help of AI. The mappings and the code example were checked against Pipedream workflows converted and run in n8n 2.x.
Top comments (0)