Yes. n8n's source control pushes workflow JSON to a Git branch, and a pull overwrites the target instance. The feature is on Business and Enterprise plans.
n8n's own documentation says "you shouldn't view n8n's source control as full version control." Here is what it does and where the gaps are.
| Capability | What it does | Where it stops |
|---|---|---|
| Storage format | Pushes workflow JSON, tags, and credential stubs to a Git branch | Format is workflow JSON. The diff is node positions, connection arrays, and unchanged configuration |
| Diff view | Shows added, modified, and deleted nodes before you pull | A one-parameter change buries the reviewer in thousands of lines of JSON |
| Merge | Environments map to separate branches | No merge. A pull replaces the entire workflow. No conflict detection |
| Rollback | Can pull a previous branch state | Overwrites everything on the target instance. No per-version revert |
| Pull requests | PRs happen in GitHub or GitLab | n8n has no awareness of them. Review happens externally |
| Credentials | Pushes stubs with ID, name, and type | Values not synced. Recreate credentials on each instance |
| Availability | Works with GitHub, GitLab, and other Git providers | Business and Enterprise plans only. Community Edition has no version control |
A Task is an AI automation written in Python, hosted on a managed runtime. A developer writes the script; anyone runs it from a form. Integrations, model calls, version control, and logging are built in.
Model and provider agnostic.
A task is a Python script. Diffs are line-level and readable. Every save is a version, and any version restores in one click.
issues = aisle.integrations.github.list_issues( state="open", labels="needs-triage", ) for issue in issues: triage = aisle.ai.run_prompt( slug="triage-issue", variables={ "title": issue["title"], "body": issue["body"], }, ) aisle.integrations.github.update_issue( issue["number"], labels=[triage["category"]], ) aisle.integrations.slack.create_message( f"#{triage['team']}", text=f"New {triage['category']}: {issue['title']}", )
A canvas change is a JSON diff. A code change is a line you can read, approve, and revert. Every run is logged with what happened.
A change to a retry count, a prompt slug, or a routing rule shows up as the line that changed. In a workflow JSON diff, the same change is buried in thousands of lines of node positions and connection metadata.
Every save writes a version with a changelog note, author, and timestamp. Open any version to see its code or toggle to a line-level diff against the previous one. Restore in one click, and the current draft is saved as a new version so nothing is lost.
tests.py is versioned in the same revision as the task code. The diff shows whether the tests moved with the change, and tests run in a sandbox so they cannot fire a real integration or bill a model call.
def test_bug_routes_to_engineering(): result = triage_issue( title="App crashes on login", body="Stack trace: ...", ) assert result["category"] == "bug" assert result["team"] == "engineering" def test_feature_routes_to_product(): result = triage_issue( title="Add dark mode", body="Would be nice to have...", ) assert result["category"] == "feature"
On Business and Enterprise plans, n8n has source control that pushes workflow JSON to Git branches. Community Edition users have no built-in version control. Third-party tools and API-based backup workflows exist as workarounds.
n8n's source control shows added, modified, and deleted nodes before a pull. The underlying diff is JSON, so what a reviewer sees is node positions, connection arrays, and parameter objects. A community-built visual diff tool renders the changes as a color-coded node graph.
With source control, you can pull a previous branch state. Without it, you re-import an older JSON export. Neither is a one-click revert to a specific revision.
No. Version history is built into the platform. Every save is a version with a line-level diff, and any version restores in one click. There is no repo, CI pipeline, or deploy target to configure.
No. The runtime is proprietary and there is no self-hosted edition. If self-hosting and source access are requirements, n8n is the better answer.
There is no importer. Describe the workflow to the builder and it drafts the task as code you then edit. Budget time for it and start with something low-risk. See the full qbash vs n8n comparison for migration steps.
Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.
Open the editor, write a script against your connected accounts, and put it on a trigger. Or describe it, and the builder drafts the task as code you edit.