What this workflow does
This workflow automatically backs up n8n workflows to a GitHub repository. It checks each local workflow and compares it with the saved version on GitHub. It creates new files or updates existing ones if changes are detected. If no change happens, it skips the update. This saves time and avoids manual errors in backup.
The main problem solved is avoiding manual exporting and syncing of workflows that takes hours and can cause mistakes or missed updates. The outcome is safe, version-controlled backups stored on GitHub without extra effort.
Who should use this workflow
This is for people who manage many n8n workflows and want to keep their backups saved automatically on GitHub. It fits those who want to save time and improve reliability in version control. Users of self-host self-host n8n or local n8n setups will find it useful.
Tools and services used
- n8n Local REST API: To fetch current workflows.
- GitHub API: To get, create, or update workflow JSON files.
- n8n Nodes: HTTP Request, Function, GitHub, Merge, Switch, SplitInBatches, Manual Trigger.
Inputs, Processing Steps, and Output
Inputs
- Local n8n workflows fetched via REST API.
- Existing workflow JSON backup files from GitHub repository.
Processing Steps
- Split the workflows array to process items one by one.
- Fetch each workflow’s file from GitHub if it exists.
- Get detailed full JSON for each workflow from local n8n.
- Compare GitHub and local workflow JSON for changes.
- Use a switch to route each workflow as “same”, “different”, or “new”.
- Skip actions for unchanged workflows.
- Edit files on GitHub if workflows are changed.
- Create new files on GitHub if workflows are new.
Output
Updated or new workflow JSON files in the GitHub repository matched with local workflows. Unchanged workflow backups remain untouched.
Beginner step-by-step: How to use this in n8n
Step 1: Import the workflow
Use the Download button to get the workflow file.
Go to the n8n editor and choose Import from File to load the workflow.
Step 2: Add credentials
Insert your GitHub API credentials with proper access to the backup repository.
Ensure the HTTP Request nodes can reach your local or cloud n8n REST API URL. Change URL if not on localhost.
Step 3: Configure repository info
In the Globals Set node, update repo.owner, repo.name, and repo.path to your GitHub account and folder.
Step 4: Test the workflow
Run the workflow manually with the Manual Trigger node to verify it fetches workflows and compares them correctly.
Step 5: Activate for ongoing use
Turn on the workflow by toggling the switch for automated runs.
Optionally, replace Manual Trigger with a Cron node to schedule daily backups.
Explanation of key code snippet for comparison
The isDiffOrNew function node compares JSON from GitHub and local n8n workflows.
It decodes the GitHub file content from Base64 and orders keys alphabetically in both JSON objects. Then it compares the JSON strings.
If they are exactly the same, it sets status to “same”. If different, it sets “different”. If no file found on GitHub, it sets “new”.
// File Returned with Content
if (Object.keys(items[0].json).includes("content")) {
var origWorkflow = eval("(\"+Buffer.from(items[0].json.content, 'base64').toString()+")");
var n8nWorkflow = (items[1].json.data);
var orderedOriginal = {}
var orderedActual = {}
Object.keys(origWorkflow).sort().forEach(function(key) {
orderedOriginal[key] = origWorkflow[key];
});
Object.keys(n8nWorkflow).sort().forEach(function(key) {
orderedActual[key] = n8nWorkflow[key];
});
if ( JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual) ) {
items[0].json.github_status = "same";
items[0].json.content_decoded = orderedOriginal;
} else {
items[0].json.github_status = "different";
items[0].json.content_decoded = orderedOriginal;
items[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);
}
} else {
var n8nWorkflow = (items[1].json.data);
var orderedActual = {}
Object.keys(n8nWorkflow).sort().forEach(function(key) {
orderedActual[key] = n8nWorkflow[key];
});
items[0].json.github_status = "new";
items[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);
}
return items;Edge cases and error fixes
- 404 GitHub File Not Found: Happens when file is not on GitHub yet. Use the “new” path with create node to fix.
- GitHub API Rate Limits: Too many requests cause errors. Keep batch size to 1 and add delays or upgrade GitHub plan.
- False “different” comparison: Happens if JSON keys reorder. The workflow orders keys before comparing, so keep that logic unchanged.
Customization options
- Change backup folder by editing
repo.pathin Globals node. - Increase batch size in SplitInBatches to process more workflows at once, but watch API limits.
- Edit commit messages in GitHub nodes for better version notes.
- Add email notifications after updates with Gmail or SMTP nodes.
- Clone workflow and change repo data to back up to more repositories.
Summary of benefits and results
✓ Save time by automating workflow backups.
✓ Avoid manual errors and missed updates.
✓ Keep version history of workflows in GitHub.
✓ Process workflows one by one to avoid conflicts.
✓ Flexible scheduling with manual or Cron triggers.
