Skip to content

N8N Export to GitHub

The N8N Export GitHub workflow automatically exports modified N8N workflows to a dedicated GitHub repository. It enables versioning, easy restoration, and keeps a history of changes.

FeatureDescription
Incremental exportOnly modified workflows are exported
Smart filteringComparison of updatedAt timestamps
Automatic manifestMetadata for all workflows
Credential extractionLists used credentials (without secrets)
Telegram notificationSummary of created/modified files
Multiple triggersSchedule, manual, or webhook
stacks_vps_n8n_exports/
├── README.md # Auto-generated with stats
├── manifest.json # Metadata + updatedAt
├── credentials-manifest.json # Credentials list (without secrets)
└── workflows/
├── orchestrateur-telegram.json
├── notification-hub.json
└── *.json

ProblemWithout exportWith export
Workflow lossN8N DB corruption = everything lostRestore from GitHub
No historyCannot roll backFull Git history
Team syncManual export by emailShared repository
DocumentationWorkflows not documentedAuto-generated README
ApproachAdvantageDrawback
Full exportSimpleUseless commits, large diffs
Incremental exportRelevant commits, clean historyFiltering complexity

no changes

modified

Triggers

Schedule · Sunday 04:00

Manual

Webhook

Get Manifest from GitHub

List All Workflows · N8N API

Filter Modified · diff updatedAt

'No changes' notification

Loop · Get full workflow data

Generate JSON + README + manifest

Loop · Push to GitHub · create or update

Telegram Notification

TriggerFrequencyUsage
ScheduleSunday 4 AMWeekly backup
ManualOn-demandTests and debug
WebhookOn-demandClaude Code integration

Triggering via webhook:

Fenêtre de terminal
source /home/guillaume/stacks_vps/n8n-exports/.env
curl -s -X POST "$WEBHOOK_URL" \
-H "X-Export-Token: $X_EXPORT_TOKEN"

Filter Modified (Code):

const manifestNode = $('Get Manifest').first();
let existingMap = new Map();
if (manifestNode.json.content) {
const manifest = JSON.parse(
Buffer.from(manifestNode.json.content, 'base64').toString('utf8')
);
existingMap = new Map(
manifest.workflows.map(w => [w.id, w.updatedAt])
);
}
const workflows = $input.all();
const modified = workflows.filter(wf => {
const prevUpdatedAt = existingMap.get(wf.json.id);
return !prevUpdatedAt || prevUpdatedAt !== wf.json.updatedAt;
});
if (modified.length === 0) {
return [{ json: { noChanges: true } }];
}
return modified;

manifest.json:

{
"exported_at": "2026-01-20T04:00:00.000Z",
"workflow_count": 25,
"active_count": 18,
"inactive_count": 7,
"workflows": [
{
"id": "abc123",
"name": "Orchestrateur Telegram",
"active": true,
"updatedAt": "2026-01-19T15:30:00.000Z"
}
]
}

credentials-manifest.json:

{
"exported_at": "2026-01-20T04:00:00.000Z",
"credentials": [
{ "id": "1", "name": "Telegram Bot", "type": "telegramApi" },
{ "id": "2", "name": "GitHub PAT", "type": "gitHubApi" }
]
}
*N8N WORKFLOWS EXPORT*
28/01/2026 04:00
*Created (1):*
- new-workflow
*Updated (3):*
- orchestrateur-telegram
- notification-hub
- manifest
Unchanged: 21
[View on GitHub](https://github.com/...)
CredentialTypeUsage
n8n accountn8n APIList/Get workflows
PAT (classic)GitHub APIGet/Create/Edit files
Telegram BotTelegram APINotifications

LimitImpactMitigation
No automatic restoreManual import in N8NRestore script planned
Credentials not exportedManually recreate after restoreOnly names are saved
Git history onlyNo one-click rollbackGitHub UI for diffs

If automatic restore is needed:

  • Create a restore-from-GitHub workflow
  • Selection of workflow and version
  • Import via the N8N API

If multiple N8N instances:

  • Adapt the manifest per instance
  • Bidirectional sync between instances
  • Conflict handling

If workflow volume grows:

  • Per-category export (active only)
  • Compression of older exports
  • Git retention policy
Fenêtre de terminal
# View recent exports
ls -la n8n-exports/workflows/
# View local changes
cd n8n-exports && git status
# Compare with a previous version
git diff HEAD~1 workflows/orchestrateur-telegram.json
# Restore a workflow
# 1. Copy the JSON from GitHub
# 2. N8N → Import workflow → Paste JSON
ProblemCheck
No exportWorkflow active? Cron correct?
401 GitHubValid PAT? Repo permissions?
Constant “No changes”manifest.json corrupted? Delete and re-run
Duplicate filesVerify updatedAt filtering