If you’ve heard about n8n and want to get started, this guide walks you through everything from installation to building your first real automation workflow. By the end, you’ll have a running n8n instance and understand how to connect apps and trigger automated tasks.
What is n8n?
n8n (pronounced “n-eight-n”) is an open-source workflow automation platform. Think of it as a self-hosted Zapier — but with no per-task pricing, full control over your data, and support for custom code at every step.
It runs as a web application that you can host on any server, VPS, or even your local machine. You build workflows by connecting nodes — each node is an integration (Slack, Notion, Gmail, HTTP request, OpenAI, etc.) or a logic step (If, Loop, Set, Merge).
Why use n8n instead of Zapier or Make?
- Self-hosted: your data never leaves your server
- No per-run costs: unlimited workflow executions on your own instance
- Open source: the full source code is available on GitHub
- Code nodes: drop into JavaScript or Python at any step
- AI-native: built-in nodes for OpenAI, Anthropic, Hugging Face, and more
Prerequisites
Before installing, you’ll need:
- A Linux server, VPS, or local machine with Docker installed
- At least 1 GB RAM (2 GB recommended)
- A domain name if you want to access n8n from the internet (optional for local use)
If you don’t have Docker, install it with:
curl -fsSL https://get.docker.com | sh
Installing n8n with Docker
The fastest way to get n8n running is with Docker. This single command starts n8n locally:
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Open http://localhost:5678 in your browser. You’ll see the n8n setup screen — create an owner account and you’re in.
Production setup with Docker Compose
For a persistent, production-ready installation, use Docker Compose with a persistent volume:
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.yourdomain.com
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.yourdomain.com/
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Start it with:
docker compose up -d
Add a reverse proxy (Caddy or Nginx) in front to handle HTTPS. A simple Caddy configuration:
n8n.yourdomain.com {
reverse_proxy localhost:5678
}
Understanding the n8n Interface
Once you’re logged in, you’ll see the main canvas. The key areas are:
- Canvas — where you build workflows by adding and connecting nodes
- Left sidebar — node library (search for integrations here)
- Executions — history of all workflow runs
- Credentials — where you store API keys securely
- Workflows — list of all your saved workflows
Creating Your First Workflow
Let’s build a simple automation: every morning at 8am, fetch the top 5 Hacker News stories and send them to a Telegram chat.
Step 1: Add a Schedule Trigger
Click the + button on the canvas. Search for Schedule and add the “Schedule Trigger” node.
Configure it:
- Trigger interval: Days
- Days between triggers: 1
- Trigger at hour: 8
- Trigger at minute: 0
Step 2: Fetch Hacker News stories
Add a second node: search for HTTP Request.
Configure it:
- Method: GET
- URL:
https://hacker-news.firebaseio.com/v3/topstories.json?print=pretty
This returns an array of story IDs. We only want the first 5.
Step 3: Split into individual IDs
Add a Code node after the HTTP Request:
const ids = $input.first().json.slice(0, 5);
return ids.map(id => ({ json: { id } }));
This turns the array into 5 separate items that will flow through the workflow one at a time.
Step 4: Fetch each story
Add another HTTP Request node:
- Method: GET
- URL:
https://hacker-news.firebaseio.com/v3/item/{{ $json.id }}.json?print=pretty
The {{ $json.id }} expression pulls the ID from the previous node dynamically.
Step 5: Aggregate and send to Telegram
First, store your Telegram bot token in Credentials → Add Credential → Telegram API.
Add a Telegram node configured to send a message. In the message field, use an expression to format the stories:
HN Top 5 for today:
{{ $input.all().map((item, i) => `${i+1}. ${item.json.title}\n${item.json.url}`).join('\n\n') }}
Step 6: Activate the workflow
Click Save, then toggle the workflow Active switch in the top right. n8n will now run this every morning at 8am automatically.
Key Concepts to Master
Expressions
Expressions let you reference data from previous nodes using double curly braces:
{{ $json.fieldName }} // current node's data
{{ $('NodeName').first().json.field }} // data from a specific node
{{ $now.toISO() }} // current timestamp
Data flow
n8n passes data between nodes as items — arrays of JSON objects. When a node receives 5 items, it typically runs once for each item (fan-out). Some nodes like “Merge” combine items back together.
Credentials
Never hardcode API keys in workflow nodes. Always store them in Settings → Credentials. Once stored, they appear in a dropdown inside each node that needs authentication.
Error handling
Add an Error Trigger node to catch workflow failures. Connect it to a Slack or email node to get notified when something breaks. You can also enable automatic retries on individual nodes via the node settings.
Useful Built-in Nodes
| Node | Use case |
|---|---|
| HTTP Request | Call any REST API |
| Webhook | Receive data from external services |
| Schedule Trigger | Run workflows on a schedule |
| Code | Custom JavaScript or Python logic |
| If | Branch your workflow conditionally |
| Merge | Combine data from multiple branches |
| Set | Transform or rename fields |
| OpenAI | Call GPT models directly |
| Google Sheets | Read/write spreadsheet data |
| Notion | Read/write Notion databases |
Common Beginner Mistakes
Forgetting to activate the workflow. A workflow only runs automatically when it’s set to Active. The toggle is in the top-right corner of the canvas.
Not saving credentials properly. If a node shows a credential error, check that you’ve added the correct credential type in Settings → Credentials and selected it in the node.
Using $json instead of $input. In newer versions of n8n, $json refers to the current item’s data, while $input.first().json refers to the input item. When in doubt, use the expression editor (click the {{}} icon next to any field) to browse available data.
Next Steps
Once you’re comfortable with basic workflows, explore:
- n8n AI Agent node — build autonomous AI agents that can browse the web, read databases, and take actions
- Sub-workflows — break complex automations into reusable building blocks
- Custom nodes — build your own integrations using the n8n SDK
- Webhook triggers — react to real-time events from Stripe, GitHub, or any service that supports webhooks
The n8n documentation at docs.n8n.io is comprehensive and searchable — start there once you’ve built your first few workflows and want to go deeper.