The question we get every week
A founder asks: "should I build this in n8n or in code?" The answer is almost never the one they want. It's usually a third option they hadn't considered. Here's how we decide, and why "do it manually" is more often the right call than people think.
When n8n wins
n8n (and Make, and Zapier, and the rest of that family) is the right answer when:
- The workflow is mostly glue — pull from system A, transform, push to system B. Not much branching, not much state.
- It needs to change weekly based on what your sales or ops team learns. Code requires a deploy; a node graph doesn't.
- The integrations are off-the-shelf — Slack, Gmail, HubSpot, Notion, Airtable. n8n has 400+ pre-built connectors and you'd be writing OAuth flows from scratch otherwise.
- The team that owns it is non-engineering. A marketer can read an n8n graph. They can't read a TypeScript service.
The classic fit is "send a Slack alert when a HubSpot deal moves to negotiation, with a summary generated by Claude." That's a 15-minute n8n build. The same thing in custom code is two days, six dependencies, and a Vercel deployment.
When custom code wins
Custom code wins when:
- The workflow has non-trivial state across multiple steps — retries, idempotency, partial failure recovery
- The latency budget is tight — n8n's executor adds 100–300ms per node, which compounds fast
- You need proper error handling and observability — every n8n workflow ends up with try/catch nodes shaped like a Christmas tree
- The workflow will be called from another system — API endpoints with strict contracts, not just background jobs
- You're moving regulated data — n8n's audit story is thin, and most regulated stacks won't tolerate it in the loop
The classic fit is "a webhook from our voice agent triggers a multi-step compliance check, persists the result, and may escalate to a human reviewer." That's where n8n falls apart and a 300-line TypeScript service is cleaner.
When the answer is "do it manually"
Here's the one nobody wants to hear. A lot of AI workflows you'd consider automating shouldn't be automated yet. Not because the technology can't, but because you don't yet understand the workflow well enough to automate it.
Signs you should keep it manual a little longer:
- You can't write down the workflow as a checklist without three "it depends" branches
- The volume is < 10 instances per week — automation will pay back in months, not days
- The cost of getting it wrong is high and your eval set is empty
- You're automating it because it's interesting, not because it's a bottleneck
Run the workflow by hand for two more weeks. Take notes on what trips you up. Then automate, and you'll automate the right thing.
The hybrid pattern we use
For most clients we end up at a hybrid: n8n owns the boring glue (notifications, CRM sync, reporting) and a small TypeScript service owns the agentic core (the model calls, the state machine, the audit trail). n8n calls the service via webhook. The service calls back to n8n when it's done.
This split lets the non-engineering team iterate on what they own without touching the regulated core, and lets the engineering team keep the parts that matter under proper version control and testing.
Takeaway
n8n is a force multiplier for ops glue. Custom code is mandatory for anything stateful, regulated, or latency-sensitive. And the question you should ask first is whether the workflow is well-understood enough to automate at all. The answer changes more often than you'd think.