n8n is an open-source workflow automation tool that lets you connect APIs, databases, and services without writing backend code. It is similar in concept to Zapier or Make (formerly Integromat) but can be self-hosted, has a more powerful data transformation model, and has a code node that lets you drop into JavaScript or Python when you need more control.
What n8n does
n8n workflows consist of nodes connected by edges. Each node performs an operation: fetch data from an API, filter a list, transform a record, write to a database, send a notification. Data flows between nodes as JSON arrays.
You build workflows through a visual editor, connecting nodes and configuring their parameters. A typical workflow might:
- Trigger on a schedule (every hour) or an event (webhook from an external service)
- Fetch records from an API
- Filter to only new records since the last run
- Transform the data format
- Write to a database
- Send a Slack notification with a summary
This is functionally similar to writing a Python script, but the visual model makes it accessible to people who are not comfortable writing code, and the built-in integrations (n8n has 400+ connectors) eliminate a lot of boilerplate.
Self-hosting vs. n8n cloud
n8n can be run as a Docker container, making self-hosting straightforward. This gives you:
- Full data privacy — data stays on your infrastructure
- No per-execution pricing (you pay for the server, not per run)
- Ability to modify and extend n8n itself
n8n also offers a managed cloud service if you prefer not to operate the infrastructure.
The code node
One of n8n's strongest features is the Code node, which lets you write arbitrary JavaScript (or Python in some versions) as a node in your workflow. This means you are never constrained by what the built-in nodes can do — when you hit a limit, you drop into code.
// Transform items in the Code node
const results = [];
for (const item of $input.all()) {
results.push({
json: {
id: item.json.id,
name: item.json.first_name + " " + item.json.last_name,
email: item.json.email.toLowerCase(),
created: new Date(item.json.created_at * 1000).toISOString(),
}
});
}
return results;
This hybrid of visual and code makes n8n more powerful than pure no-code tools while remaining accessible.
Expressions and data transformation
n8n uses a JavaScript expression syntax for referencing data from other nodes:
{{ $node["HTTP Request"].json["user"]["email"] }}
{{ $now.toISO() }}
{{ $json.price * 1.19 }}
This is powerful but can become difficult to read in complex workflows. Understanding n8n's data model — that each node outputs an array of items, each with a json property — is essential for working with expressions effectively.
Error handling and reliability
n8n supports error handling at the workflow level: you can define what happens when a node fails — stop the workflow, continue to the next node, or route to an error handling sub-workflow.
For production workflows, important patterns:
- Use the Error Trigger node to capture and handle failures explicitly
- Send notifications when critical workflows fail
- Use n8n's built-in logging to debug execution history
- Set appropriate timeout values for HTTP requests
When n8n fits well
n8n is a good fit when:
- You need to connect APIs and services with relatively simple logic
- Your team includes non-engineers who will build or maintain workflows
- You need self-hosted for data privacy
- You want to avoid per-execution pricing at volume
It is less well suited when:
- You need complex error handling and reliability guarantees that belong in proper application code
- The workflow logic is complex enough that visual programming becomes harder to understand than code
- You need sophisticated testing and CI/CD for your automation
At some point, a sufficiently complex n8n workflow is harder to reason about than a well-tested Python script. The right tool depends on the complexity of your needs and the technical depth of your team.
Summary
n8n provides visual workflow automation with 400+ pre-built integrations, self-hosting capability, and a Code node for dropping into JavaScript when needed. It occupies a useful middle ground between pure no-code tools (like Zapier) and custom code — more flexible than the former, more accessible than the latter. It works best for connecting APIs and services with moderate logic, especially when the automation will be maintained by non-engineers.