Migrate from Zapier to n8n
Workflow automation / iPaaS · full migration guide
Zapier → n8n is the textbook example of a manual rebuild migration: Zapier doesn't export Zaps in any structured form, and n8n doesn't accept Zapier definitions. What you migrate is the concept (Trigger → Action chain) and the credentials. The good news is that n8n's 400+ integration nodes cover virtually every common Zapier connector, and most Zaps are 2-4 steps that take 5-10 minutes to recreate. Plan one workflow at a time, validated with test data, then cut over. The bonus: every n8n node can call a `Function` step with arbitrary JavaScript, so workflows that hit Zapier's complexity ceiling often simplify dramatically in n8n.
Prerequisites
- Zapier admin access (you need to view all Zaps and their connected accounts).
- A self-hosted n8n instance — see /zapier/ for the 10-minute docker-compose recipe and ~$5-20/mo VPS sizing depending on workflow volume.
- n8n's queue mode (Redis-backed) if you'll run more than a few hundred workflow executions per day — set `EXECUTIONS_MODE=queue` and add a Redis container.
- API credentials for each integrated service (Slack bot token, Notion integration token, Airtable PAT, Google service account, etc.) — Zapier abstracts these via OAuth, n8n re-OAuths or accepts API keys directly.
- A list of every active Zap, ranked by mission-criticality — the top 20% you'll port first.
Step 1 — Export from Zapier
-
Inventory your Zaps
Zapier dashboard → Zaps. Filter by 'On' to see active workflows. Note for each: trigger app + event, action app(s) + action(s), filter steps, formatter steps, paths (branches), tasks consumed/month. Tasks/month is your cost driver — high-volume Zaps are the migration priority.
-
Document each Zap as a flowchart
For each Zap, screenshot the editor view or write the steps as: `[Trigger: New row in Airtable / Table=Leads] → [Filter: Status = 'New'] → [Action: Slack post in #sales] → [Action: Send Gmail to lead.email]`. This is the spec for the n8n rebuild — n8n's node graph maps near 1:1.
-
Capture filter and formatter logic
Zapier's Filter and Formatter steps have specific operators (Date/Time → Format, Numbers → Spreadsheet-style Formula, Text → Replace). Save the exact configurations — these become n8n's IF, Set, and Code nodes.
-
List connected accounts
Zapier → Apps. List each connected account (Slack workspace name, Google account email, Airtable workspace). For each, you'll re-authenticate or generate fresh API credentials in n8n. Some apps (Notion, Airtable) need a fresh integration token from the source app's developer settings; OAuth-based apps (Slack, Google) re-OAuth in the n8n UI.
Step 2 — Import into n8n
-
Stand up n8n with persistent Postgres
Don't use the default SQLite for production. docker-compose with: n8n + Postgres + (Redis for queue mode). Set `DB_TYPE=postgresdb`, `DB_POSTGRESDB_HOST=...`. Sign in at the n8n URL; first user becomes owner.
-
Add credentials for every integration
n8n → Credentials → New. For each service in your Zap inventory: paste the API key or run the OAuth flow. n8n stores credentials encrypted with the `N8N_ENCRYPTION_KEY` env var — set this to a random 32-char value at install time and back it up; losing it means re-authing everything.
-
Recreate one Zap, end-to-end
Pick the simplest Zap. n8n → Workflows → New. Add a trigger node matching the Zapier trigger (e.g. `Airtable Trigger` for new row). Add the action node (e.g. `Slack` → Post Message). Wire them. Test with a sample row. Compare output to what Zapier produces — confirm the field mapping matches before moving on.
-
Translate filter/formatter steps
Zapier Filter → n8n IF node. Zapier Formatter → n8n Set node (for renaming/restructuring) or Code node (for arbitrary JS — e.g. `return [{json: {date: new Date(items[0].json.timestamp).toISOString()}}]`). Test each branch.
-
Handle webhooks and HTTP
Zapier Webhooks (Catch Hook) → n8n Webhook node. n8n gives you a unique URL per workflow. Update the source service to POST to the n8n URL instead. The payload is the same shape — n8n exposes it as the trigger's output.
-
Activate and watch
n8n workflow → Active toggle. Send a real production event. Watch n8n → Executions for the run. Compare the output to what Zapier did. Once stable, deactivate the corresponding Zapier Zap.
-
Migrate the rest in waves
Top-20%-by-volume first. Then the long tail. Some Zaps will require a node that's not in n8n's catalog — write a custom node (TypeScript, ~50 lines) or call the third-party API directly via the HTTP Request node.
Field / concept mapping
| Zapier | n8n | Notes |
|---|---|---|
| Zapier Zap | n8n Workflow | 1:1 conceptually. Manual recreate. |
| Zapier Trigger | n8n Trigger node | Each Zapier app's triggers (e.g. Slack New Message in Channel) have an n8n equivalent (Slack Trigger → New Message in Channel). |
| Zapier Action | n8n Action node | Same. n8n has Action nodes for the same apps. For apps n8n doesn't support natively, use the HTTP Request node to call the API directly. |
| Zapier Filter | n8n IF node | Boolean logic on field values. n8n's IF supports the same comparators (equals, contains, greater than, regex match). |
| Zapier Formatter (Date/Time, Text, Numbers) | n8n Set node + Code node | Set node for static rewrites, Code node for arbitrary transforms. JavaScript expressions everywhere; n8n's expression syntax is `{{$json.fieldName}}`. |
| Zapier Path (branching) | n8n Switch node | Switch node accepts multiple match expressions and routes to different downstream branches. |
| Zapier Webhook (Catch Hook) | n8n Webhook trigger | Each n8n workflow's webhook gets a unique URL. Update sender configs. |
| Zapier Webhook (POST to URL) | n8n HTTP Request node | Generic HTTP — same fields: URL, method, headers, body. |
| Zapier Sub-zap / Reusable action | n8n Sub-Workflow node | n8n supports calling another workflow as a subroutine. Cleaner than Zapier's reusable action concept. |
| Zapier Schedule (every N minutes) | n8n Schedule trigger / Cron | n8n Schedule trigger uses cron-like syntax. For sub-minute intervals, the polling interval is what you set on the trigger node directly. |
| Zapier OAuth connection | n8n OAuth credential | Re-OAuth per service in n8n's UI. Most major apps (Slack, Google, Microsoft) have first-class OAuth credentials in n8n. |
Downtime estimate
Zero downtime via dual-run: keep Zapier active while you rebuild and test. Cutover per workflow is instant — flip Zapier off, n8n is already on. Per-workflow rebuild: 5-30 minutes for a simple 2-3 step Zap; 1-2 hours for a complex Zap with paths, filters, and custom formatters. A full migration of 50 Zaps is typically 1-2 weeks of part-time work spread over the migrator's calendar.
Common gotchas
- n8n's license is the Sustainable Use License — fair-code, not OSI. Free for internal business use including self-host; restricts re-selling n8n as a SaaS. If you need pure OSI/MIT, evaluate Activepieces (also covered on /zapier/) instead.
- n8n credentials are encrypted with `N8N_ENCRYPTION_KEY`. Losing this env var bricks all stored credentials — back it up the moment you set it.
- Default n8n SQLite is fine for testing, painful for production (executions table grows fast). Switch to Postgres at install time.
- Some Zapier connectors are wrappers around scraped APIs (e.g. some legacy CRM connectors). n8n doesn't have these — you'll fall back to the HTTP Request node + the official API.
- Zapier's task counter and n8n's execution counter measure differently. n8n is unmetered (your VPS is the cost ceiling), but high-volume polling triggers can max out a small VPS. Move to webhook-based triggers where possible.
Rollback plan
Per-workflow rollback is a single click — re-enable the Zapier Zap, disable the n8n workflow. Zapier holds onto Zaps for 90 days after deactivation, so if you cancel the Zapier subscription too quickly there's a re-activation grace period. Keep Zapier paid for at least the duration of the migration window, then a 30-day buffer post-cutover to catch any workflows whose translation has subtle bugs.
Looking for setup time, monthly cost, and other alternatives? See Self-host Zapier.