Invidious Musings

[PR] Uncovering the Tradeoffs of n8n

Recently, I discovered n8n, a workflow automation tool targeted as an open source and cheaper alternative to Zapier. At SecondShop, I used the tool to integrate with our Shopify storefront to avoid adding and deploying webhooks.

Like all low code tools: it’s great! Until it isn’t.

An example of a simple n8n workflow

An example of a simple n8n workflow.

n8n is different from other low code tools I’ve tried in that I can export all data and migrate hassle free. If it can’t do what you want, host your own API, and get n8n to call it during a workflow. For simple flows with lots of integrations, n8n improved my development speed and joy for calling many APIs.

Since n8n has no schema enforcement, you have to run the workflow and see it fail, like with all dynamically typed languages. Being able to pin production test data on past executions makes it simple to build workflows and debug past executions.

So, n8n is production ready… for a solo developer.

  • “Do you want collaboration?” Upgrade your plan.
  • “What about version control?” Give us money.
  • “Oooh, you wanna fetch some itty bitty secrets from GCP?” Too bad, pay me.

Remember how I said “simple workflows” are great to develop? Complicated workflows balloon into an eyesore as you deactivate, move aside, or move nodes between sub-workflows (n8n’s answer to “functions”).

An example of a complex n8n workflow

I didn’t think there was a literal way to create spaghetti code until I used n8n.

Not only is it not scalable, but in my experience, the n8n-mcp server produces unreliable outputs, so I couldn’t develop with AI. There’s even a quirk where you can’t forward binary data, aka file blobs, to nodes not immediately next to where the file was attached, so you need to have a bunch of merge nodes to reference the files.

And then, there’s the Form Node. I know if one were to reach for low code frontends, a backend automation solution would be far behind Retool, Appsmith, Budibase, or Tooljet. n8n’s answer to a frontend is its Forms, which handle routing, components, and input validation; a backend developer’s dream.

But what happens when you need a custom loading state, a search field, custom input validation, or error displays? You guessed it: DIY. It’s not a magic bullet, but I guess nothing is.